[][openvswitch][mt7986][Fix some code defect]

[Description]
Fix crash issue when do over night test in ovs_packet_cmd_execute()
Change to forward multicast packet unregistered to all vports instead of drop

[Release-log]
N/A

Change-Id: Iecc153a877cb1a5bf3ed6814e709110f0390b8d0
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7028152
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch
index b3dd782..c707ee2 100755
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch
@@ -1,5 +1,5 @@
 diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
-index 9e8a5c4..9104255 100644
+index 9e8a5c4..d5bf30d 100644
 --- a/net/openvswitch/actions.c
 +++ b/net/openvswitch/actions.c
 @@ -919,6 +919,10 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
@@ -13,11 +13,10 @@
  
  	if (likely(vport)) {
  		u16 mru = OVS_CB(skb)->mru;
-@@ -933,7 +937,31 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
+@@ -933,6 +937,32 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
  
  		if (likely(!mru ||
  		           (skb->len <= mru + vport->dev->hard_header_len))) {
--			ovs_vport_send(vport, skb, ovs_key_mac_proto(key));
 +			if (is_multicast_addr(skb) && !is_igmp_mld(skb)) {
 +				mdb = vport->mdb;
 +				spin_lock(&mdb->tbl_lock);
@@ -37,17 +36,18 @@
 +							memcpy(skb_cpy->data, entry->eth_addr, ETH_ALEN);
 +							ovs_vport_send(vport, skb_cpy, ovs_key_mac_proto(key));
 +						}
++						spin_unlock(&mdb->tbl_lock);
++						kfree_skb(skb);
++						return;
 +					}
 +				}
 +				spin_unlock(&mdb->tbl_lock);
-+				kfree_skb(skb);
-+			} else
-+				ovs_vport_send(vport, skb, ovs_key_mac_proto(key));
++			}
+ 			ovs_vport_send(vport, skb, ovs_key_mac_proto(key));
  		} else if (mru <= vport->dev->mtu) {
  			struct net *net = read_pnet(&dp->net);
- 
 diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
-index 4f097bd..2f39f07 100644
+index 4f097bd..9a2a8c0 100644
 --- a/net/openvswitch/datapath.c
 +++ b/net/openvswitch/datapath.c
 @@ -11,6 +11,9 @@
@@ -60,7 +60,7 @@
  #include <linux/jhash.h>
  #include <linux/delay.h>
  #include <linux/time.h>
-@@ -530,6 +533,262 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
+@@ -530,6 +533,270 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
  	return err;
  }
  
@@ -278,17 +278,25 @@
 +			if (ipv6_addr_is_ll_all_nodes(&group_addr.u.ip6))
 +				return 0;
 +
-+			if (group_type == MLD2_MODE_IS_EXCLUDE ||
++			if ((group_type == MLD2_MODE_IS_EXCLUDE ||
 +				group_type == MLD2_CHANGE_TO_EXCLUDE ||
-+				group_type == MLD2_ALLOW_NEW_SOURCES)
++				group_type == MLD2_ALLOW_NEW_SOURCES) &&
++				num_of_source == 0)
 +				ovs_multicast_add_group(&group_addr, dl_src, input_vport);
 +			else if ((group_type == MLD2_MODE_IS_INCLUDE ||
 +					group_type == MLD2_CHANGE_TO_INCLUDE ||
 +					group_type == MLD2_BLOCK_OLD_SOURCES) &&
 +					num_of_source == 0)
 +				ovs_multicast_leave_group(&group_addr, dl_src, input_vport);
-+
-+			grec += (4 + (num_of_source + 1) * sizeof(struct in6_addr) + aux_data_len);
++			else {
++				pr_info("%s(): group_type(%d), aux_data_len(%d),\
++						num_of_source(%d), group_addr(%pI6)\n",
++						__func__, group_type, aux_data_len,
++						num_of_source, &group_addr.u.ip6);
++				return 0;
++			}
++			grec = (struct mld2_grec *)((u8 *)grec + sizeof(struct mld2_grec)
++										+ aux_data_len * sizeof(u32));
 +		}
 +		break;
 +	case ICMPV6_MGM_QUERY:
@@ -323,7 +331,7 @@
  static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
  {
  	struct ovs_header *ovs_header = info->userhdr;
-@@ -604,6 +863,9 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
+@@ -604,6 +871,9 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
  	OVS_CB(packet)->input_vport = input_vport;
  	sf_acts = rcu_dereference(flow->sf_acts);
  
@@ -333,7 +341,7 @@
  	local_bh_disable();
  	err = ovs_execute_actions(dp, packet, sf_acts, &flow->key);
  	local_bh_enable();
-@@ -2183,6 +2445,9 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
+@@ -2183,6 +2453,9 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
  	struct datapath *dp;
  	struct vport *vport;
  	unsigned int new_headroom;
@@ -343,7 +351,7 @@
  	int err;
  
  	reply = ovs_vport_cmd_alloc_info();
-@@ -2210,6 +2475,22 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
+@@ -2210,6 +2483,22 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
  	if (netdev_get_fwd_headroom(vport->dev) == dp->max_headroom)
  		update_headroom = true;