forked from Minki/linux
net-next: add dev_loopback_xmit() to avoid duplicate code
Add dev_loopback_xmit() in order to deduplicate functions ip_dev_loopback_xmit() (in net/ipv4/ip_output.c) and ip6_dev_loopback_xmit() (in net/ipv6/ip6_output.c). I was about to reinvent the wheel when I noticed that ip_dev_loopback_xmit() and ip6_dev_loopback_xmit() do exactly what I need and are not IP-only functions, but they were not available to reuse elsewhere. ip6_dev_loopback_xmit() does not have line "skb_dst_force(skb);", but I understand that this is harmless, and should be in dev_loopback_xmit(). Signed-off-by: Michel Machado <michel@digirati.com.br> CC: "David S. Miller" <davem@davemloft.net> CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> CC: James Morris <jmorris@namei.org> CC: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> CC: Patrick McHardy <kaber@trash.net> CC: Eric Dumazet <edumazet@google.com> CC: Jiri Pirko <jpirko@redhat.com> CC: "Michał Mirosław" <mirq-linux@rere.qmqm.pl> CC: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
de063b7040
commit
95603e2293
@ -1627,6 +1627,7 @@ extern int dev_alloc_name(struct net_device *dev, const char *name);
|
|||||||
extern int dev_open(struct net_device *dev);
|
extern int dev_open(struct net_device *dev);
|
||||||
extern int dev_close(struct net_device *dev);
|
extern int dev_close(struct net_device *dev);
|
||||||
extern void dev_disable_lro(struct net_device *dev);
|
extern void dev_disable_lro(struct net_device *dev);
|
||||||
|
extern int dev_loopback_xmit(struct sk_buff *newskb);
|
||||||
extern int dev_queue_xmit(struct sk_buff *skb);
|
extern int dev_queue_xmit(struct sk_buff *skb);
|
||||||
extern int register_netdevice(struct net_device *dev);
|
extern int register_netdevice(struct net_device *dev);
|
||||||
extern void unregister_netdevice_queue(struct net_device *dev,
|
extern void unregister_netdevice_queue(struct net_device *dev,
|
||||||
|
@ -2475,6 +2475,23 @@ static void skb_update_prio(struct sk_buff *skb)
|
|||||||
static DEFINE_PER_CPU(int, xmit_recursion);
|
static DEFINE_PER_CPU(int, xmit_recursion);
|
||||||
#define RECURSION_LIMIT 10
|
#define RECURSION_LIMIT 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dev_loopback_xmit - loop back @skb
|
||||||
|
* @skb: buffer to transmit
|
||||||
|
*/
|
||||||
|
int dev_loopback_xmit(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
skb_reset_mac_header(skb);
|
||||||
|
__skb_pull(skb, skb_network_offset(skb));
|
||||||
|
skb->pkt_type = PACKET_LOOPBACK;
|
||||||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
WARN_ON(!skb_dst(skb));
|
||||||
|
skb_dst_force(skb);
|
||||||
|
netif_rx_ni(skb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dev_loopback_xmit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dev_queue_xmit - transmit a buffer
|
* dev_queue_xmit - transmit a buffer
|
||||||
* @skb: buffer to transmit
|
* @skb: buffer to transmit
|
||||||
|
@ -113,19 +113,6 @@ int ip_local_out(struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ip_local_out);
|
EXPORT_SYMBOL_GPL(ip_local_out);
|
||||||
|
|
||||||
/* dev_loopback_xmit for use with netfilter. */
|
|
||||||
static int ip_dev_loopback_xmit(struct sk_buff *newskb)
|
|
||||||
{
|
|
||||||
skb_reset_mac_header(newskb);
|
|
||||||
__skb_pull(newskb, skb_network_offset(newskb));
|
|
||||||
newskb->pkt_type = PACKET_LOOPBACK;
|
|
||||||
newskb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
||||||
WARN_ON(!skb_dst(newskb));
|
|
||||||
skb_dst_force(newskb);
|
|
||||||
netif_rx_ni(newskb);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
|
static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
|
||||||
{
|
{
|
||||||
int ttl = inet->uc_ttl;
|
int ttl = inet->uc_ttl;
|
||||||
@ -281,7 +268,7 @@ int ip_mc_output(struct sk_buff *skb)
|
|||||||
if (newskb)
|
if (newskb)
|
||||||
NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,
|
NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,
|
||||||
newskb, NULL, newskb->dev,
|
newskb, NULL, newskb->dev,
|
||||||
ip_dev_loopback_xmit);
|
dev_loopback_xmit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Multicasts with ttl 0 must not go beyond the host */
|
/* Multicasts with ttl 0 must not go beyond the host */
|
||||||
@ -296,7 +283,7 @@ int ip_mc_output(struct sk_buff *skb)
|
|||||||
struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
|
struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
|
||||||
if (newskb)
|
if (newskb)
|
||||||
NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb,
|
NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb,
|
||||||
NULL, newskb->dev, ip_dev_loopback_xmit);
|
NULL, newskb->dev, dev_loopback_xmit);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL,
|
return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL,
|
||||||
|
@ -83,19 +83,6 @@ int ip6_local_out(struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ip6_local_out);
|
EXPORT_SYMBOL_GPL(ip6_local_out);
|
||||||
|
|
||||||
/* dev_loopback_xmit for use with netfilter. */
|
|
||||||
static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
|
|
||||||
{
|
|
||||||
skb_reset_mac_header(newskb);
|
|
||||||
__skb_pull(newskb, skb_network_offset(newskb));
|
|
||||||
newskb->pkt_type = PACKET_LOOPBACK;
|
|
||||||
newskb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
||||||
WARN_ON(!skb_dst(newskb));
|
|
||||||
|
|
||||||
netif_rx_ni(newskb);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ip6_finish_output2(struct sk_buff *skb)
|
static int ip6_finish_output2(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dst_entry *dst = skb_dst(skb);
|
struct dst_entry *dst = skb_dst(skb);
|
||||||
@ -121,7 +108,7 @@ static int ip6_finish_output2(struct sk_buff *skb)
|
|||||||
if (newskb)
|
if (newskb)
|
||||||
NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING,
|
NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING,
|
||||||
newskb, NULL, newskb->dev,
|
newskb, NULL, newskb->dev,
|
||||||
ip6_dev_loopback_xmit);
|
dev_loopback_xmit);
|
||||||
|
|
||||||
if (ipv6_hdr(skb)->hop_limit == 0) {
|
if (ipv6_hdr(skb)->hop_limit == 0) {
|
||||||
IP6_INC_STATS(dev_net(dev), idev,
|
IP6_INC_STATS(dev_net(dev), idev,
|
||||||
|
Loading…
Reference in New Issue
Block a user