1 // SPDX-License-Identifier: GPL-2.0
2 /* Bareudp: UDP tunnel encasulation for different Payload types like
4 * Copyright (c) 2019 Nokia, Inc.
5 * Authors: Martin Varghese, <martin.varghese@nokia.com>
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/etherdevice.h>
13 #include <linux/hash.h>
14 #include <net/dst_metadata.h>
15 #include <net/gro_cells.h>
16 #include <net/rtnetlink.h>
17 #include <net/protocol.h>
18 #include <net/ip6_tunnel.h>
19 #include <net/ip_tunnels.h>
20 #include <net/udp_tunnel.h>
21 #include <net/bareudp.h>
23 #define BAREUDP_BASE_HLEN sizeof(struct udphdr)
24 #define BAREUDP_IPV4_HLEN (sizeof(struct iphdr) + \
25 sizeof(struct udphdr))
26 #define BAREUDP_IPV6_HLEN (sizeof(struct ipv6hdr) + \
27 sizeof(struct udphdr))
29 static bool log_ecn_error
= true;
30 module_param(log_ecn_error
, bool, 0644);
31 MODULE_PARM_DESC(log_ecn_error
, "Log packets received with corrupted ECN");
33 /* per-network namespace private data for this module */
35 static unsigned int bareudp_net_id
;
38 struct list_head bareudp_list
;
41 /* Pseudo network device */
43 struct net
*net
; /* netns for packet i/o */
44 struct net_device
*dev
; /* netdev for bareudp tunnel */
48 bool multi_proto_mode
;
49 struct socket __rcu
*sock
;
50 struct list_head next
; /* bareudp node on namespace list */
51 struct gro_cells gro_cells
;
54 static int bareudp_udp_encap_recv(struct sock
*sk
, struct sk_buff
*skb
)
56 struct metadata_dst
*tun_dst
= NULL
;
57 struct bareudp_dev
*bareudp
;
58 unsigned short family
;
64 bareudp
= rcu_dereference_sk_user_data(sk
);
68 if (skb
->protocol
== htons(ETH_P_IP
))
73 if (bareudp
->ethertype
== htons(ETH_P_IP
)) {
76 if (skb_copy_bits(skb
, BAREUDP_BASE_HLEN
, &ipversion
,
78 bareudp
->dev
->stats
.rx_dropped
++;
84 proto
= htons(ETH_P_IP
);
85 } else if (ipversion
== 6 && bareudp
->multi_proto_mode
) {
86 proto
= htons(ETH_P_IPV6
);
88 bareudp
->dev
->stats
.rx_dropped
++;
91 } else if (bareudp
->ethertype
== htons(ETH_P_MPLS_UC
)) {
92 struct iphdr
*tunnel_hdr
;
94 tunnel_hdr
= (struct iphdr
*)skb_network_header(skb
);
95 if (tunnel_hdr
->version
== 4) {
96 if (!ipv4_is_multicast(tunnel_hdr
->daddr
)) {
97 proto
= bareudp
->ethertype
;
98 } else if (bareudp
->multi_proto_mode
&&
99 ipv4_is_multicast(tunnel_hdr
->daddr
)) {
100 proto
= htons(ETH_P_MPLS_MC
);
102 bareudp
->dev
->stats
.rx_dropped
++;
107 struct ipv6hdr
*tunnel_hdr_v6
;
109 tunnel_hdr_v6
= (struct ipv6hdr
*)skb_network_header(skb
);
111 ipv6_addr_type((struct in6_addr
*)&tunnel_hdr_v6
->daddr
);
112 if (!(addr_type
& IPV6_ADDR_MULTICAST
)) {
113 proto
= bareudp
->ethertype
;
114 } else if (bareudp
->multi_proto_mode
&&
115 (addr_type
& IPV6_ADDR_MULTICAST
)) {
116 proto
= htons(ETH_P_MPLS_MC
);
118 bareudp
->dev
->stats
.rx_dropped
++;
123 proto
= bareudp
->ethertype
;
126 if (iptunnel_pull_header(skb
, BAREUDP_BASE_HLEN
,
128 !net_eq(bareudp
->net
,
129 dev_net(bareudp
->dev
)))) {
130 bareudp
->dev
->stats
.rx_dropped
++;
133 tun_dst
= udp_tun_rx_dst(skb
, family
, TUNNEL_KEY
, 0, 0);
135 bareudp
->dev
->stats
.rx_dropped
++;
138 skb_dst_set(skb
, &tun_dst
->dst
);
139 skb
->dev
= bareudp
->dev
;
140 oiph
= skb_network_header(skb
);
141 skb_reset_network_header(skb
);
142 skb_reset_mac_header(skb
);
144 if (!ipv6_mod_enabled() || family
== AF_INET
)
145 err
= IP_ECN_decapsulate(oiph
, skb
);
147 err
= IP6_ECN_decapsulate(oiph
, skb
);
151 if (!ipv6_mod_enabled() || family
== AF_INET
)
152 net_info_ratelimited("non-ECT from %pI4 "
154 &((struct iphdr
*)oiph
)->saddr
,
155 ((struct iphdr
*)oiph
)->tos
);
157 net_info_ratelimited("non-ECT from %pI6\n",
158 &((struct ipv6hdr
*)oiph
)->saddr
);
161 ++bareudp
->dev
->stats
.rx_frame_errors
;
162 ++bareudp
->dev
->stats
.rx_errors
;
168 err
= gro_cells_receive(&bareudp
->gro_cells
, skb
);
169 if (likely(err
== NET_RX_SUCCESS
))
170 dev_sw_netstats_rx_add(bareudp
->dev
, len
);
174 /* Consume bad packet */
180 static int bareudp_err_lookup(struct sock
*sk
, struct sk_buff
*skb
)
185 static int bareudp_init(struct net_device
*dev
)
187 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
190 dev
->tstats
= netdev_alloc_pcpu_stats(struct pcpu_sw_netstats
);
194 err
= gro_cells_init(&bareudp
->gro_cells
, dev
);
196 free_percpu(dev
->tstats
);
202 static void bareudp_uninit(struct net_device
*dev
)
204 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
206 gro_cells_destroy(&bareudp
->gro_cells
);
207 free_percpu(dev
->tstats
);
210 static struct socket
*bareudp_create_sock(struct net
*net
, __be16 port
)
212 struct udp_port_cfg udp_conf
;
216 memset(&udp_conf
, 0, sizeof(udp_conf
));
218 if (ipv6_mod_enabled())
219 udp_conf
.family
= AF_INET6
;
221 udp_conf
.family
= AF_INET
;
223 udp_conf
.local_udp_port
= port
;
224 /* Open UDP socket */
225 err
= udp_sock_create(net
, &udp_conf
, &sock
);
229 udp_allow_gso(sock
->sk
);
233 /* Create new listen socket if needed */
234 static int bareudp_socket_create(struct bareudp_dev
*bareudp
, __be16 port
)
236 struct udp_tunnel_sock_cfg tunnel_cfg
;
239 sock
= bareudp_create_sock(bareudp
->net
, port
);
241 return PTR_ERR(sock
);
243 /* Mark socket as an encapsulation socket */
244 memset(&tunnel_cfg
, 0, sizeof(tunnel_cfg
));
245 tunnel_cfg
.sk_user_data
= bareudp
;
246 tunnel_cfg
.encap_type
= 1;
247 tunnel_cfg
.encap_rcv
= bareudp_udp_encap_recv
;
248 tunnel_cfg
.encap_err_lookup
= bareudp_err_lookup
;
249 tunnel_cfg
.encap_destroy
= NULL
;
250 setup_udp_tunnel_sock(bareudp
->net
, sock
, &tunnel_cfg
);
252 rcu_assign_pointer(bareudp
->sock
, sock
);
256 static int bareudp_open(struct net_device
*dev
)
258 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
261 ret
= bareudp_socket_create(bareudp
, bareudp
->port
);
265 static void bareudp_sock_release(struct bareudp_dev
*bareudp
)
269 sock
= bareudp
->sock
;
270 rcu_assign_pointer(bareudp
->sock
, NULL
);
272 udp_tunnel_sock_release(sock
);
275 static int bareudp_stop(struct net_device
*dev
)
277 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
279 bareudp_sock_release(bareudp
);
283 static int bareudp_xmit_skb(struct sk_buff
*skb
, struct net_device
*dev
,
284 struct bareudp_dev
*bareudp
,
285 const struct ip_tunnel_info
*info
)
287 bool xnet
= !net_eq(bareudp
->net
, dev_net(bareudp
->dev
));
288 bool use_cache
= ip_tunnel_dst_cache_usable(skb
, info
);
289 struct socket
*sock
= rcu_dereference(bareudp
->sock
);
290 bool udp_sum
= !!(info
->key
.tun_flags
& TUNNEL_CSUM
);
291 const struct ip_tunnel_key
*key
= &info
->key
;
302 rt
= ip_route_output_tunnel(skb
, dev
, bareudp
->net
, &saddr
, info
,
303 IPPROTO_UDP
, use_cache
);
308 skb_tunnel_check_pmtu(skb
, &rt
->dst
,
309 BAREUDP_IPV4_HLEN
+ info
->options_len
, false);
311 sport
= udp_flow_src_port(bareudp
->net
, skb
,
312 bareudp
->sport_min
, USHRT_MAX
,
314 tos
= ip_tunnel_ecn_encap(key
->tos
, ip_hdr(skb
), skb
);
316 df
= key
->tun_flags
& TUNNEL_DONT_FRAGMENT
? htons(IP_DF
) : 0;
317 skb_scrub_packet(skb
, xnet
);
320 if (!skb_pull(skb
, skb_network_offset(skb
)))
323 min_headroom
= LL_RESERVED_SPACE(rt
->dst
.dev
) + rt
->dst
.header_len
+
324 BAREUDP_BASE_HLEN
+ info
->options_len
+ sizeof(struct iphdr
);
326 err
= skb_cow_head(skb
, min_headroom
);
330 err
= udp_tunnel_handle_offloads(skb
, udp_sum
);
334 skb_set_inner_protocol(skb
, bareudp
->ethertype
);
335 udp_tunnel_xmit_skb(rt
, sock
->sk
, skb
, saddr
, info
->key
.u
.ipv4
.dst
,
336 tos
, ttl
, df
, sport
, bareudp
->port
,
337 !net_eq(bareudp
->net
, dev_net(bareudp
->dev
)),
338 !(info
->key
.tun_flags
& TUNNEL_CSUM
));
342 dst_release(&rt
->dst
);
346 static int bareudp6_xmit_skb(struct sk_buff
*skb
, struct net_device
*dev
,
347 struct bareudp_dev
*bareudp
,
348 const struct ip_tunnel_info
*info
)
350 bool xnet
= !net_eq(bareudp
->net
, dev_net(bareudp
->dev
));
351 bool use_cache
= ip_tunnel_dst_cache_usable(skb
, info
);
352 struct socket
*sock
= rcu_dereference(bareudp
->sock
);
353 bool udp_sum
= !!(info
->key
.tun_flags
& TUNNEL_CSUM
);
354 const struct ip_tunnel_key
*key
= &info
->key
;
355 struct dst_entry
*dst
= NULL
;
356 struct in6_addr saddr
, daddr
;
365 dst
= ip6_dst_lookup_tunnel(skb
, dev
, bareudp
->net
, sock
, &saddr
, info
,
366 IPPROTO_UDP
, use_cache
);
370 skb_tunnel_check_pmtu(skb
, dst
, BAREUDP_IPV6_HLEN
+ info
->options_len
,
373 sport
= udp_flow_src_port(bareudp
->net
, skb
,
374 bareudp
->sport_min
, USHRT_MAX
,
376 prio
= ip_tunnel_ecn_encap(key
->tos
, ip_hdr(skb
), skb
);
379 skb_scrub_packet(skb
, xnet
);
382 if (!skb_pull(skb
, skb_network_offset(skb
)))
385 min_headroom
= LL_RESERVED_SPACE(dst
->dev
) + dst
->header_len
+
386 BAREUDP_BASE_HLEN
+ info
->options_len
+ sizeof(struct ipv6hdr
);
388 err
= skb_cow_head(skb
, min_headroom
);
392 err
= udp_tunnel_handle_offloads(skb
, udp_sum
);
396 daddr
= info
->key
.u
.ipv6
.dst
;
397 udp_tunnel6_xmit_skb(dst
, sock
->sk
, skb
, dev
,
398 &saddr
, &daddr
, prio
, ttl
,
399 info
->key
.label
, sport
, bareudp
->port
,
400 !(info
->key
.tun_flags
& TUNNEL_CSUM
));
408 static bool bareudp_proto_valid(struct bareudp_dev
*bareudp
, __be16 proto
)
410 if (bareudp
->ethertype
== proto
)
413 if (!bareudp
->multi_proto_mode
)
416 if (bareudp
->ethertype
== htons(ETH_P_MPLS_UC
) &&
417 proto
== htons(ETH_P_MPLS_MC
))
420 if (bareudp
->ethertype
== htons(ETH_P_IP
) &&
421 proto
== htons(ETH_P_IPV6
))
427 static netdev_tx_t
bareudp_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
429 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
430 struct ip_tunnel_info
*info
= NULL
;
433 if (!bareudp_proto_valid(bareudp
, skb
->protocol
)) {
438 info
= skb_tunnel_info(skb
);
439 if (unlikely(!info
|| !(info
->mode
& IP_TUNNEL_INFO_TX
))) {
445 if (ipv6_mod_enabled() && info
->mode
& IP_TUNNEL_INFO_IPV6
)
446 err
= bareudp6_xmit_skb(skb
, dev
, bareudp
, info
);
448 err
= bareudp_xmit_skb(skb
, dev
, bareudp
, info
);
458 dev
->stats
.collisions
++;
459 else if (err
== -ENETUNREACH
)
460 dev
->stats
.tx_carrier_errors
++;
462 dev
->stats
.tx_errors
++;
466 static int bareudp_fill_metadata_dst(struct net_device
*dev
,
469 struct ip_tunnel_info
*info
= skb_tunnel_info(skb
);
470 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
473 use_cache
= ip_tunnel_dst_cache_usable(skb
, info
);
475 if (!ipv6_mod_enabled() || ip_tunnel_info_af(info
) == AF_INET
) {
479 rt
= ip_route_output_tunnel(skb
, dev
, bareudp
->net
, &saddr
,
480 info
, IPPROTO_UDP
, use_cache
);
485 info
->key
.u
.ipv4
.src
= saddr
;
486 } else if (ip_tunnel_info_af(info
) == AF_INET6
) {
487 struct dst_entry
*dst
;
488 struct in6_addr saddr
;
489 struct socket
*sock
= rcu_dereference(bareudp
->sock
);
491 dst
= ip6_dst_lookup_tunnel(skb
, dev
, bareudp
->net
, sock
,
492 &saddr
, info
, IPPROTO_UDP
,
498 info
->key
.u
.ipv6
.src
= saddr
;
503 info
->key
.tp_src
= udp_flow_src_port(bareudp
->net
, skb
,
506 info
->key
.tp_dst
= bareudp
->port
;
510 static const struct net_device_ops bareudp_netdev_ops
= {
511 .ndo_init
= bareudp_init
,
512 .ndo_uninit
= bareudp_uninit
,
513 .ndo_open
= bareudp_open
,
514 .ndo_stop
= bareudp_stop
,
515 .ndo_start_xmit
= bareudp_xmit
,
516 .ndo_get_stats64
= dev_get_tstats64
,
517 .ndo_fill_metadata_dst
= bareudp_fill_metadata_dst
,
520 static const struct nla_policy bareudp_policy
[IFLA_BAREUDP_MAX
+ 1] = {
521 [IFLA_BAREUDP_PORT
] = { .type
= NLA_U16
},
522 [IFLA_BAREUDP_ETHERTYPE
] = { .type
= NLA_U16
},
523 [IFLA_BAREUDP_SRCPORT_MIN
] = { .type
= NLA_U16
},
524 [IFLA_BAREUDP_MULTIPROTO_MODE
] = { .type
= NLA_FLAG
},
527 /* Info for udev, that this is a virtual tunnel endpoint */
528 static const struct device_type bareudp_type
= {
532 /* Initialize the device structure. */
533 static void bareudp_setup(struct net_device
*dev
)
535 dev
->netdev_ops
= &bareudp_netdev_ops
;
536 dev
->needs_free_netdev
= true;
537 SET_NETDEV_DEVTYPE(dev
, &bareudp_type
);
538 dev
->features
|= NETIF_F_SG
| NETIF_F_HW_CSUM
| NETIF_F_FRAGLIST
;
539 dev
->features
|= NETIF_F_RXCSUM
;
540 dev
->features
|= NETIF_F_LLTX
;
541 dev
->features
|= NETIF_F_GSO_SOFTWARE
;
542 dev
->hw_features
|= NETIF_F_SG
| NETIF_F_HW_CSUM
| NETIF_F_FRAGLIST
;
543 dev
->hw_features
|= NETIF_F_RXCSUM
;
544 dev
->hw_features
|= NETIF_F_GSO_SOFTWARE
;
545 dev
->hard_header_len
= 0;
547 dev
->mtu
= ETH_DATA_LEN
;
548 dev
->min_mtu
= IPV4_MIN_MTU
;
549 dev
->max_mtu
= IP_MAX_MTU
- BAREUDP_BASE_HLEN
;
550 dev
->type
= ARPHRD_NONE
;
552 dev
->priv_flags
|= IFF_NO_QUEUE
;
553 dev
->flags
= IFF_POINTOPOINT
| IFF_NOARP
| IFF_MULTICAST
;
556 static int bareudp_validate(struct nlattr
*tb
[], struct nlattr
*data
[],
557 struct netlink_ext_ack
*extack
)
560 NL_SET_ERR_MSG(extack
,
561 "Not enough attributes provided to perform the operation");
567 static int bareudp2info(struct nlattr
*data
[], struct bareudp_conf
*conf
,
568 struct netlink_ext_ack
*extack
)
570 memset(conf
, 0, sizeof(*conf
));
572 if (!data
[IFLA_BAREUDP_PORT
]) {
573 NL_SET_ERR_MSG(extack
, "port not specified");
576 if (!data
[IFLA_BAREUDP_ETHERTYPE
]) {
577 NL_SET_ERR_MSG(extack
, "ethertype not specified");
581 if (data
[IFLA_BAREUDP_PORT
])
582 conf
->port
= nla_get_u16(data
[IFLA_BAREUDP_PORT
]);
584 if (data
[IFLA_BAREUDP_ETHERTYPE
])
585 conf
->ethertype
= nla_get_u16(data
[IFLA_BAREUDP_ETHERTYPE
]);
587 if (data
[IFLA_BAREUDP_SRCPORT_MIN
])
588 conf
->sport_min
= nla_get_u16(data
[IFLA_BAREUDP_SRCPORT_MIN
]);
590 if (data
[IFLA_BAREUDP_MULTIPROTO_MODE
])
591 conf
->multi_proto_mode
= true;
596 static struct bareudp_dev
*bareudp_find_dev(struct bareudp_net
*bn
,
597 const struct bareudp_conf
*conf
)
599 struct bareudp_dev
*bareudp
, *t
= NULL
;
601 list_for_each_entry(bareudp
, &bn
->bareudp_list
, next
) {
602 if (conf
->port
== bareudp
->port
)
608 static int bareudp_configure(struct net
*net
, struct net_device
*dev
,
609 struct bareudp_conf
*conf
)
611 struct bareudp_net
*bn
= net_generic(net
, bareudp_net_id
);
612 struct bareudp_dev
*t
, *bareudp
= netdev_priv(dev
);
617 t
= bareudp_find_dev(bn
, conf
);
621 if (conf
->multi_proto_mode
&&
622 (conf
->ethertype
!= htons(ETH_P_MPLS_UC
) &&
623 conf
->ethertype
!= htons(ETH_P_IP
)))
626 bareudp
->port
= conf
->port
;
627 bareudp
->ethertype
= conf
->ethertype
;
628 bareudp
->sport_min
= conf
->sport_min
;
629 bareudp
->multi_proto_mode
= conf
->multi_proto_mode
;
631 err
= register_netdevice(dev
);
635 list_add(&bareudp
->next
, &bn
->bareudp_list
);
639 static int bareudp_link_config(struct net_device
*dev
,
645 err
= dev_set_mtu(dev
, nla_get_u32(tb
[IFLA_MTU
]));
652 static void bareudp_dellink(struct net_device
*dev
, struct list_head
*head
)
654 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
656 list_del(&bareudp
->next
);
657 unregister_netdevice_queue(dev
, head
);
660 static int bareudp_newlink(struct net
*net
, struct net_device
*dev
,
661 struct nlattr
*tb
[], struct nlattr
*data
[],
662 struct netlink_ext_ack
*extack
)
664 struct bareudp_conf conf
;
667 err
= bareudp2info(data
, &conf
, extack
);
671 err
= bareudp_configure(net
, dev
, &conf
);
675 err
= bareudp_link_config(dev
, tb
);
682 bareudp_dellink(dev
, NULL
);
686 static size_t bareudp_get_size(const struct net_device
*dev
)
688 return nla_total_size(sizeof(__be16
)) + /* IFLA_BAREUDP_PORT */
689 nla_total_size(sizeof(__be16
)) + /* IFLA_BAREUDP_ETHERTYPE */
690 nla_total_size(sizeof(__u16
)) + /* IFLA_BAREUDP_SRCPORT_MIN */
691 nla_total_size(0) + /* IFLA_BAREUDP_MULTIPROTO_MODE */
695 static int bareudp_fill_info(struct sk_buff
*skb
, const struct net_device
*dev
)
697 struct bareudp_dev
*bareudp
= netdev_priv(dev
);
699 if (nla_put_be16(skb
, IFLA_BAREUDP_PORT
, bareudp
->port
))
700 goto nla_put_failure
;
701 if (nla_put_be16(skb
, IFLA_BAREUDP_ETHERTYPE
, bareudp
->ethertype
))
702 goto nla_put_failure
;
703 if (nla_put_u16(skb
, IFLA_BAREUDP_SRCPORT_MIN
, bareudp
->sport_min
))
704 goto nla_put_failure
;
705 if (bareudp
->multi_proto_mode
&&
706 nla_put_flag(skb
, IFLA_BAREUDP_MULTIPROTO_MODE
))
707 goto nla_put_failure
;
715 static struct rtnl_link_ops bareudp_link_ops __read_mostly
= {
717 .maxtype
= IFLA_BAREUDP_MAX
,
718 .policy
= bareudp_policy
,
719 .priv_size
= sizeof(struct bareudp_dev
),
720 .setup
= bareudp_setup
,
721 .validate
= bareudp_validate
,
722 .newlink
= bareudp_newlink
,
723 .dellink
= bareudp_dellink
,
724 .get_size
= bareudp_get_size
,
725 .fill_info
= bareudp_fill_info
,
728 struct net_device
*bareudp_dev_create(struct net
*net
, const char *name
,
730 struct bareudp_conf
*conf
)
732 struct nlattr
*tb
[IFLA_MAX
+ 1];
733 struct net_device
*dev
;
736 memset(tb
, 0, sizeof(tb
));
737 dev
= rtnl_create_link(net
, name
, name_assign_type
,
738 &bareudp_link_ops
, tb
, NULL
);
742 err
= bareudp_configure(net
, dev
, conf
);
747 err
= dev_set_mtu(dev
, IP_MAX_MTU
- BAREUDP_BASE_HLEN
);
751 err
= rtnl_configure_link(dev
, NULL
);
757 bareudp_dellink(dev
, NULL
);
760 EXPORT_SYMBOL_GPL(bareudp_dev_create
);
762 static __net_init
int bareudp_init_net(struct net
*net
)
764 struct bareudp_net
*bn
= net_generic(net
, bareudp_net_id
);
766 INIT_LIST_HEAD(&bn
->bareudp_list
);
770 static void bareudp_destroy_tunnels(struct net
*net
, struct list_head
*head
)
772 struct bareudp_net
*bn
= net_generic(net
, bareudp_net_id
);
773 struct bareudp_dev
*bareudp
, *next
;
775 list_for_each_entry_safe(bareudp
, next
, &bn
->bareudp_list
, next
)
776 unregister_netdevice_queue(bareudp
->dev
, head
);
779 static void __net_exit
bareudp_exit_batch_net(struct list_head
*net_list
)
785 list_for_each_entry(net
, net_list
, exit_list
)
786 bareudp_destroy_tunnels(net
, &list
);
788 /* unregister the devices gathered above */
789 unregister_netdevice_many(&list
);
793 static struct pernet_operations bareudp_net_ops
= {
794 .init
= bareudp_init_net
,
795 .exit_batch
= bareudp_exit_batch_net
,
796 .id
= &bareudp_net_id
,
797 .size
= sizeof(struct bareudp_net
),
800 static int __init
bareudp_init_module(void)
804 rc
= register_pernet_subsys(&bareudp_net_ops
);
808 rc
= rtnl_link_register(&bareudp_link_ops
);
814 unregister_pernet_subsys(&bareudp_net_ops
);
818 late_initcall(bareudp_init_module
);
820 static void __exit
bareudp_cleanup_module(void)
822 rtnl_link_unregister(&bareudp_link_ops
);
823 unregister_pernet_subsys(&bareudp_net_ops
);
825 module_exit(bareudp_cleanup_module
);
827 MODULE_ALIAS_RTNL_LINK("bareudp");
828 MODULE_LICENSE("GPL");
829 MODULE_AUTHOR("Martin Varghese <martin.varghese@nokia.com>");
830 MODULE_DESCRIPTION("Interface driver for UDP encapsulated traffic");