int ip_tunnel_init(struct net_device *dev);
void ip_tunnel_uninit(struct net_device *dev);
void ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
-int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
- struct rtnl_link_ops *ops, char *devname);
+int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
+ struct rtnl_link_ops *ops, char *devname);
-void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn);
+void ip_tunnel_delete_net(struct ip_tunnel_net *itn);
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
- const struct iphdr *tnl_params);
+ const struct iphdr *tnl_params, const u8 protocol);
int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu);
(skb_shinfo(skb)->gso_segs ?: 1) - 1);
}
-static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- int err;
- int pkt_len = skb->len - skb_transport_offset(skb);
- struct pcpu_tstats *tstats = this_cpu_ptr(dev->tstats);
+int iptunnel_xmit(struct net *net, struct rtable *rt,
+ struct sk_buff *skb,
+ __be32 src, __be32 dst, __u8 proto,
+ __u8 tos, __u8 ttl, __be16 df);
- nf_reset(skb);
+static inline void iptunnel_xmit_stats(int err,
+ struct net_device_stats *err_stats,
+ struct pcpu_tstats __percpu *stats)
+{
+ if (err > 0) {
+ struct pcpu_tstats *tstats = this_cpu_ptr(stats);
- err = ip_local_out(skb);
- if (likely(net_xmit_eval(err) == 0)) {
u64_stats_update_begin(&tstats->syncp);
- tstats->tx_bytes += pkt_len;
+ tstats->tx_bytes += err;
tstats->tx_packets++;
u64_stats_update_end(&tstats->syncp);
+ } else if (err < 0) {
+ err_stats->tx_errors++;
+ err_stats->tx_aborted_errors++;
} else {
- dev->stats.tx_errors++;
- dev->stats.tx_aborted_errors++;
+ err_stats->tx_dropped++;
}
}
#endif /* __NET_IP_TUNNELS_H */