act_mirred.c (a402eae64d0ad12b1c4a411f250d6c161e67f623) act_mirred.c (a5135bcfba7345031df45e02cd150a45add47cf8)
1/*
2 * net/sched/act_mirred.c packet mirroring and redirect actions
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 156 unchanged lines hidden (view full) ---

165{
166 struct tcf_mirred *m = to_mirred(a);
167 bool m_mac_header_xmit;
168 struct net_device *dev;
169 struct sk_buff *skb2;
170 int retval, err = 0;
171 int m_eaction;
172 int mac_len;
1/*
2 * net/sched/act_mirred.c packet mirroring and redirect actions
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 156 unchanged lines hidden (view full) ---

165{
166 struct tcf_mirred *m = to_mirred(a);
167 bool m_mac_header_xmit;
168 struct net_device *dev;
169 struct sk_buff *skb2;
170 int retval, err = 0;
171 int m_eaction;
172 int mac_len;
173 u32 at;
174
175 tcf_lastuse_update(&m->tcf_tm);
176 bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb);
177
178 rcu_read_lock();
179 m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit);
180 m_eaction = READ_ONCE(m->tcfm_eaction);
181 retval = READ_ONCE(m->tcf_action);

--- 4 unchanged lines hidden (view full) ---

186 }
187
188 if (unlikely(!(dev->flags & IFF_UP))) {
189 net_notice_ratelimited("tc mirred to Houston: device %s is down\n",
190 dev->name);
191 goto out;
192 }
193
173
174 tcf_lastuse_update(&m->tcf_tm);
175 bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb);
176
177 rcu_read_lock();
178 m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit);
179 m_eaction = READ_ONCE(m->tcfm_eaction);
180 retval = READ_ONCE(m->tcf_action);

--- 4 unchanged lines hidden (view full) ---

185 }
186
187 if (unlikely(!(dev->flags & IFF_UP))) {
188 net_notice_ratelimited("tc mirred to Houston: device %s is down\n",
189 dev->name);
190 goto out;
191 }
192
194 at = G_TC_AT(skb->tc_verd);
195 skb2 = skb_clone(skb, GFP_ATOMIC);
196 if (!skb2)
197 goto out;
198
199 /* If action's target direction differs than filter's direction,
200 * and devices expect a mac header on xmit, then mac push/pull is
201 * needed.
202 */
193 skb2 = skb_clone(skb, GFP_ATOMIC);
194 if (!skb2)
195 goto out;
196
197 /* If action's target direction differs than filter's direction,
198 * and devices expect a mac header on xmit, then mac push/pull is
199 * needed.
200 */
203 if (at != tcf_mirred_act_direction(m_eaction) && m_mac_header_xmit) {
204 if (at & AT_EGRESS) {
201 if (skb->tc_at != tcf_mirred_act_direction(m_eaction) &&
202 m_mac_header_xmit) {
203 if (!skb_at_tc_ingress(skb)) {
205 /* caught at egress, act ingress: pull mac */
206 mac_len = skb_network_header(skb) - skb_mac_header(skb);
207 skb_pull_rcsum(skb2, mac_len);
208 } else {
209 /* caught at ingress, act egress: push mac */
210 skb_push_rcsum(skb2, skb->mac_len);
211 }
212 }
213
214 /* mirror is always swallowed */
215 if (tcf_mirred_is_act_redirect(m_eaction))
204 /* caught at egress, act ingress: pull mac */
205 mac_len = skb_network_header(skb) - skb_mac_header(skb);
206 skb_pull_rcsum(skb2, mac_len);
207 } else {
208 /* caught at ingress, act egress: push mac */
209 skb_push_rcsum(skb2, skb->mac_len);
210 }
211 }
212
213 /* mirror is always swallowed */
214 if (tcf_mirred_is_act_redirect(m_eaction))
216 skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
215 skb2->tc_from = skb2->tc_at;
217
218 skb2->skb_iif = skb->dev->ifindex;
219 skb2->dev = dev;
220 if (tcf_mirred_act_direction(m_eaction) & AT_EGRESS)
221 err = dev_queue_xmit(skb2);
222 else
223 err = netif_receive_skb(skb2);
224

--- 162 unchanged lines hidden ---
216
217 skb2->skb_iif = skb->dev->ifindex;
218 skb2->dev = dev;
219 if (tcf_mirred_act_direction(m_eaction) & AT_EGRESS)
220 err = dev_queue_xmit(skb2);
221 else
222 err = netif_receive_skb(skb2);
223

--- 162 unchanged lines hidden ---