ip_output.c (24e8a2ca1f74574ad2ed1ac7af0260dd90fd911e) | ip_output.c (956fe2190820df3a6ee530204e059da508159319) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * INET An implementation of the TCP/IP protocol suite for the LINUX 4 * operating system. INET is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * The Internet Protocol (IP) output module. 8 * --- 273 unchanged lines hidden (view full) --- 282 if (err && ret == 0) 283 ret = err; 284 segs = nskb; 285 } while (segs); 286 287 return ret; 288} 289 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * INET An implementation of the TCP/IP protocol suite for the LINUX 4 * operating system. INET is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * The Internet Protocol (IP) output module. 8 * --- 273 unchanged lines hidden (view full) --- 282 if (err && ret == 0) 283 ret = err; 284 segs = nskb; 285 } while (segs); 286 287 return ret; 288} 289 |
290static int ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb) | 290static int __ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb) |
291{ 292 unsigned int mtu; | 291{ 292 unsigned int mtu; |
293 int ret; | |
294 | 293 |
295 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb); 296 if (ret) { 297 kfree_skb(skb); 298 return ret; 299 } 300 | |
301#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) 302 /* Policy lookup after SNAT yielded a new policy */ 303 if (skb_dst(skb)->xfrm) { 304 IPCB(skb)->flags |= IPSKB_REROUTED; 305 return dst_output(net, sk, skb); 306 } 307#endif 308 mtu = ip_skb_dst_mtu(sk, skb); 309 if (skb_is_gso(skb)) 310 return ip_finish_output_gso(net, sk, skb, mtu); 311 312 if (skb->len > mtu || (IPCB(skb)->flags & IPSKB_FRAG_PMTU)) 313 return ip_fragment(net, sk, skb, mtu, ip_finish_output2); 314 315 return ip_finish_output2(net, sk, skb); 316} 317 | 294#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) 295 /* Policy lookup after SNAT yielded a new policy */ 296 if (skb_dst(skb)->xfrm) { 297 IPCB(skb)->flags |= IPSKB_REROUTED; 298 return dst_output(net, sk, skb); 299 } 300#endif 301 mtu = ip_skb_dst_mtu(sk, skb); 302 if (skb_is_gso(skb)) 303 return ip_finish_output_gso(net, sk, skb, mtu); 304 305 if (skb->len > mtu || (IPCB(skb)->flags & IPSKB_FRAG_PMTU)) 306 return ip_fragment(net, sk, skb, mtu, ip_finish_output2); 307 308 return ip_finish_output2(net, sk, skb); 309} 310 |
311static int ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb) 312{ 313 int ret; 314 315 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb); 316 switch (ret) { 317 case NET_XMIT_SUCCESS: 318 return __ip_finish_output(net, sk, skb); 319 case NET_XMIT_CN: 320 return __ip_finish_output(net, sk, skb) ? : ret; 321 default: 322 kfree_skb(skb); 323 return ret; 324 } 325} 326 |
|
318static int ip_mc_finish_output(struct net *net, struct sock *sk, 319 struct sk_buff *skb) 320{ 321 int ret; 322 323 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb); | 327static int ip_mc_finish_output(struct net *net, struct sock *sk, 328 struct sk_buff *skb) 329{ 330 int ret; 331 332 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb); |
324 if (ret) { | 333 switch (ret) { 334 case NET_XMIT_SUCCESS: 335 return dev_loopback_xmit(net, sk, skb); 336 case NET_XMIT_CN: 337 return dev_loopback_xmit(net, sk, skb) ? : ret; 338 default: |
325 kfree_skb(skb); 326 return ret; 327 } | 339 kfree_skb(skb); 340 return ret; 341 } |
328 329 return dev_loopback_xmit(net, sk, skb); | |
330} 331 332int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb) 333{ 334 struct rtable *rt = skb_rtable(skb); 335 struct net_device *dev = rt->dst.dev; 336 337 /* --- 1298 unchanged lines hidden --- | 342} 343 344int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb) 345{ 346 struct rtable *rt = skb_rtable(skb); 347 struct net_device *dev = rt->dst.dev; 348 349 /* --- 1298 unchanged lines hidden --- |