diff --git a/feeds/ipq807x/ipq807x/patches/221-net-sched-act_mirred-Rename-tcfm_ok_push-to-tcfm_mac.patch b/feeds/ipq807x/ipq807x/patches/221-net-sched-act_mirred-Rename-tcfm_ok_push-to-tcfm_mac.patch new file mode 100644 index 000000000..199fee15e --- /dev/null +++ b/feeds/ipq807x/ipq807x/patches/221-net-sched-act_mirred-Rename-tcfm_ok_push-to-tcfm_mac.patch @@ -0,0 +1,75 @@ +From: Shmulik Ladkani +Date: Thu, 13 Oct 2016 09:06:41 +0300 +Subject: [PATCH] net/sched: act_mirred: Rename tcfm_ok_push to + tcfm_mac_header_xmit and make it a bool + +'tcfm_ok_push' specifies whether a mac_len sized push is needed upon +egress to the target device (if action is performed at ingress). + +Rename it to 'tcfm_mac_header_xmit' as this is actually an attribute of +the target device (and use a bool instead of int). + +This allows to decouple the attribute from the action to be taken. + +Signed-off-by: Shmulik Ladkani +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +--- + +--- a/include/net/tc_act/tc_mirred.h ++++ b/include/net/tc_act/tc_mirred.h +@@ -7,7 +7,7 @@ struct tcf_mirred { + struct tcf_common common; + int tcfm_eaction; + int tcfm_ifindex; +- int tcfm_ok_push; ++ bool tcfm_mac_header_xmit; + struct net_device __rcu *tcfm_dev; + struct list_head tcfm_list; + }; +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -55,10 +55,11 @@ static int tcf_mirred_init(struct net *n + int bind) + { + struct nlattr *tb[TCA_MIRRED_MAX + 1]; ++ bool mac_header_xmit = false; + struct tc_mirred *parm; + struct tcf_mirred *m; + struct net_device *dev; +- int ret, ok_push = 0; ++ int ret; + + if (nla == NULL) + return -EINVAL; +@@ -86,10 +87,10 @@ static int tcf_mirred_init(struct net *n + case ARPHRD_IPGRE: + case ARPHRD_VOID: + case ARPHRD_NONE: +- ok_push = 0; ++ mac_header_xmit = false; + break; + default: +- ok_push = 1; ++ mac_header_xmit = true; + break; + } + } else { +@@ -123,7 +124,7 @@ static int tcf_mirred_init(struct net *n + dev_put(rcu_dereference_protected(m->tcfm_dev, 1)); + dev_hold(dev); + rcu_assign_pointer(m->tcfm_dev, dev); +- m->tcfm_ok_push = ok_push; ++ m->tcfm_mac_header_xmit = mac_header_xmit; + } + + if (ret == ACT_P_CREATED) { +@@ -169,7 +170,7 @@ static int tcf_mirred(struct sk_buff *sk + goto out; + + if (!(at & AT_EGRESS)) { +- if (m->tcfm_ok_push) ++ if (m->tcfm_mac_header_xmit) + skb_push_rcsum(skb2, skb->mac_len); + } + diff --git a/feeds/ipq807x/ipq807x/patches/222-net-sched-act_mirred-Refactor-detection-whether-dev-.patch b/feeds/ipq807x/ipq807x/patches/222-net-sched-act_mirred-Refactor-detection-whether-dev-.patch new file mode 100644 index 000000000..b752c5c3f --- /dev/null +++ b/feeds/ipq807x/ipq807x/patches/222-net-sched-act_mirred-Refactor-detection-whether-dev-.patch @@ -0,0 +1,36 @@ +From: Shmulik Ladkani +Date: Thu, 13 Oct 2016 09:06:42 +0300 +Subject: [PATCH] net/sched: act_mirred: Refactor detection whether dev needs + xmit at mac header + +Move detection logic that tests whether device expects skb data to point +at mac_header upon xmit into a function. + +Signed-off-by: Shmulik Ladkani +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +--- + +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -80,19 +80,7 @@ static int tcf_mirred_init(struct net *n + dev = __dev_get_by_index(net, parm->ifindex); + if (dev == NULL) + return -ENODEV; +- switch (dev->type) { +- case ARPHRD_TUNNEL: +- case ARPHRD_TUNNEL6: +- case ARPHRD_SIT: +- case ARPHRD_IPGRE: +- case ARPHRD_VOID: +- case ARPHRD_NONE: +- mac_header_xmit = false; +- break; +- default: +- mac_header_xmit = true; +- break; +- } ++ mac_header_xmit = dev_is_mac_header_xmit(dev); + } else { + dev = NULL; + } diff --git a/feeds/ipq807x/ipq807x/patches/223-net-sched-act_mirred-Implement-ingress-actions.patch b/feeds/ipq807x/ipq807x/patches/223-net-sched-act_mirred-Implement-ingress-actions.patch new file mode 100644 index 000000000..14373e539 --- /dev/null +++ b/feeds/ipq807x/ipq807x/patches/223-net-sched-act_mirred-Implement-ingress-actions.patch @@ -0,0 +1,125 @@ +From: Shmulik Ladkani +Date: Thu, 13 Oct 2016 09:06:44 +0300 +Subject: [PATCH] net/sched: act_mirred: Implement ingress actions + +Up until now, 'action mirred' supported only egress actions (either +TCA_EGRESS_REDIR or TCA_EGRESS_MIRROR). + +This patch implements the corresponding ingress actions +TCA_INGRESS_REDIR and TCA_INGRESS_MIRROR. + +This allows attaching filters whose target is to hand matching skbs into +the rx processing of a specified device. + +Signed-off-by: Shmulik Ladkani +Cc: Jamal Hadi Salim +Cc: Eric Dumazet +Cc: Cong Wang +Tested-by: Jamal Hadi Salim +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +--- + +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -33,6 +33,25 @@ + static LIST_HEAD(mirred_list); + static DEFINE_SPINLOCK(mirred_list_lock); + ++static bool tcf_mirred_is_act_redirect(int action) ++{ ++ return action == TCA_EGRESS_REDIR || action == TCA_INGRESS_REDIR; ++} ++ ++static u32 tcf_mirred_act_direction(int action) ++{ ++ switch (action) { ++ case TCA_EGRESS_REDIR: ++ case TCA_EGRESS_MIRROR: ++ return AT_EGRESS; ++ case TCA_INGRESS_REDIR: ++ case TCA_INGRESS_MIRROR: ++ return AT_INGRESS; ++ default: ++ BUG(); ++ } ++} ++ + static void tcf_mirred_release(struct tc_action *a, int bind) + { + struct tcf_mirred *m = to_mirred(a); +@@ -72,6 +91,8 @@ static int tcf_mirred_init(struct net *n + switch (parm->eaction) { + case TCA_EGRESS_MIRROR: + case TCA_EGRESS_REDIR: ++ case TCA_INGRESS_REDIR: ++ case TCA_INGRESS_MIRROR: + break; + default: + return -EINVAL; +@@ -129,9 +150,12 @@ static int tcf_mirred(struct sk_buff *sk + struct tcf_result *res) + { + struct tcf_mirred *m = a->priv; ++ bool m_mac_header_xmit; + struct net_device *dev; + struct sk_buff *skb2; +- int retval, err; ++ int retval, err = 0; ++ int m_eaction; ++ int mac_len; + u32 at; + + tcf_lastuse_update(&m->tcf_tm); +@@ -139,6 +163,8 @@ static int tcf_mirred(struct sk_buff *sk + bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb); + + rcu_read_lock(); ++ m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit); ++ m_eaction = READ_ONCE(m->tcfm_eaction); + retval = READ_ONCE(m->tcf_action); + dev = rcu_dereference(m->tcfm_dev); + if (unlikely(!dev)) { +@@ -157,24 +183,37 @@ static int tcf_mirred(struct sk_buff *sk + if (!skb2) + goto out; + +- if (!(at & AT_EGRESS)) { +- if (m->tcfm_mac_header_xmit) ++ /* If action's target direction differs than filter's direction, ++ * and devices expect a mac header on xmit, then mac push/pull is ++ * needed. ++ */ ++ if (at != tcf_mirred_act_direction(m_eaction) && m_mac_header_xmit) { ++ if (at & AT_EGRESS) { ++ /* caught at egress, act ingress: pull mac */ ++ mac_len = skb_network_header(skb) - skb_mac_header(skb); ++ skb_pull_rcsum(skb2, mac_len); ++ } else { ++ /* caught at ingress, act egress: push mac */ + skb_push_rcsum(skb2, skb->mac_len); ++ } + } + + /* mirror is always swallowed */ +- if (m->tcfm_eaction != TCA_EGRESS_MIRROR) ++ if (tcf_mirred_is_act_redirect(m_eaction)) + skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at); + + skb2->skb_iif = skb->dev->ifindex; + skb2->dev = dev; + skb_sender_cpu_clear(skb2); +- err = dev_queue_xmit(skb2); ++ if (tcf_mirred_act_direction(m_eaction) & AT_EGRESS) ++ err = dev_queue_xmit(skb2); ++ else ++ err = netif_receive_skb(skb2); + + if (err) { + out: + qstats_overlimit_inc(this_cpu_ptr(m->common.cpu_qstats)); +- if (m->tcfm_eaction != TCA_EGRESS_MIRROR) ++ if (tcf_mirred_is_act_redirect(m_eaction)) + retval = TC_ACT_SHOT; + } + rcu_read_unlock();