1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Bareudp: UDP tunnel encasulation for different Payload types like |
3 | * MPLS, NSH, IP, etc. |
4 | * Copyright (c) 2019 Nokia, Inc. |
5 | * Authors: Martin Varghese, <martin.varghese@nokia.com> |
6 | */ |
7 | |
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
9 | |
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> |
22 | |
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)) |
28 | |
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" ); |
32 | |
33 | /* per-network namespace private data for this module */ |
34 | |
35 | static unsigned int bareudp_net_id; |
36 | |
37 | struct bareudp_net { |
38 | struct list_head bareudp_list; |
39 | }; |
40 | |
41 | struct bareudp_conf { |
42 | __be16 ethertype; |
43 | __be16 port; |
44 | u16 sport_min; |
45 | bool multi_proto_mode; |
46 | }; |
47 | |
48 | /* Pseudo network device */ |
49 | struct bareudp_dev { |
50 | struct net *net; /* netns for packet i/o */ |
51 | struct net_device *dev; /* netdev for bareudp tunnel */ |
52 | __be16 ethertype; |
53 | __be16 port; |
54 | u16 sport_min; |
55 | bool multi_proto_mode; |
56 | struct socket __rcu *sock; |
57 | struct list_head next; /* bareudp node on namespace list */ |
58 | struct gro_cells gro_cells; |
59 | }; |
60 | |
61 | static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) |
62 | { |
63 | struct metadata_dst *tun_dst = NULL; |
64 | struct bareudp_dev *bareudp; |
65 | unsigned short family; |
66 | unsigned int len; |
67 | __be16 proto; |
68 | void *oiph; |
69 | int err; |
70 | |
71 | bareudp = rcu_dereference_sk_user_data(sk); |
72 | if (!bareudp) |
73 | goto drop; |
74 | |
75 | if (skb->protocol == htons(ETH_P_IP)) |
76 | family = AF_INET; |
77 | else |
78 | family = AF_INET6; |
79 | |
80 | if (bareudp->ethertype == htons(ETH_P_IP)) { |
81 | __u8 ipversion; |
82 | |
83 | if (skb_copy_bits(skb, BAREUDP_BASE_HLEN, to: &ipversion, |
84 | len: sizeof(ipversion))) { |
85 | bareudp->dev->stats.rx_dropped++; |
86 | goto drop; |
87 | } |
88 | ipversion >>= 4; |
89 | |
90 | if (ipversion == 4) { |
91 | proto = htons(ETH_P_IP); |
92 | } else if (ipversion == 6 && bareudp->multi_proto_mode) { |
93 | proto = htons(ETH_P_IPV6); |
94 | } else { |
95 | bareudp->dev->stats.rx_dropped++; |
96 | goto drop; |
97 | } |
98 | } else if (bareudp->ethertype == htons(ETH_P_MPLS_UC)) { |
99 | struct iphdr *tunnel_hdr; |
100 | |
101 | tunnel_hdr = (struct iphdr *)skb_network_header(skb); |
102 | if (tunnel_hdr->version == 4) { |
103 | if (!ipv4_is_multicast(addr: tunnel_hdr->daddr)) { |
104 | proto = bareudp->ethertype; |
105 | } else if (bareudp->multi_proto_mode && |
106 | ipv4_is_multicast(addr: tunnel_hdr->daddr)) { |
107 | proto = htons(ETH_P_MPLS_MC); |
108 | } else { |
109 | bareudp->dev->stats.rx_dropped++; |
110 | goto drop; |
111 | } |
112 | } else { |
113 | int addr_type; |
114 | struct ipv6hdr *tunnel_hdr_v6; |
115 | |
116 | tunnel_hdr_v6 = (struct ipv6hdr *)skb_network_header(skb); |
117 | addr_type = |
118 | ipv6_addr_type(addr: (struct in6_addr *)&tunnel_hdr_v6->daddr); |
119 | if (!(addr_type & IPV6_ADDR_MULTICAST)) { |
120 | proto = bareudp->ethertype; |
121 | } else if (bareudp->multi_proto_mode && |
122 | (addr_type & IPV6_ADDR_MULTICAST)) { |
123 | proto = htons(ETH_P_MPLS_MC); |
124 | } else { |
125 | bareudp->dev->stats.rx_dropped++; |
126 | goto drop; |
127 | } |
128 | } |
129 | } else { |
130 | proto = bareudp->ethertype; |
131 | } |
132 | |
133 | if (iptunnel_pull_header(skb, BAREUDP_BASE_HLEN, |
134 | inner_proto: proto, |
135 | xnet: !net_eq(net1: bareudp->net, |
136 | net2: dev_net(dev: bareudp->dev)))) { |
137 | bareudp->dev->stats.rx_dropped++; |
138 | goto drop; |
139 | } |
140 | tun_dst = udp_tun_rx_dst(skb, family, TUNNEL_KEY, tunnel_id: 0, md_size: 0); |
141 | if (!tun_dst) { |
142 | bareudp->dev->stats.rx_dropped++; |
143 | goto drop; |
144 | } |
145 | skb_dst_set(skb, dst: &tun_dst->dst); |
146 | skb->dev = bareudp->dev; |
147 | oiph = skb_network_header(skb); |
148 | skb_reset_network_header(skb); |
149 | skb_reset_mac_header(skb); |
150 | |
151 | if (!ipv6_mod_enabled() || family == AF_INET) |
152 | err = IP_ECN_decapsulate(oiph, skb); |
153 | else |
154 | err = IP6_ECN_decapsulate(oipv6h: oiph, skb); |
155 | |
156 | if (unlikely(err)) { |
157 | if (log_ecn_error) { |
158 | if (!ipv6_mod_enabled() || family == AF_INET) |
159 | net_info_ratelimited("non-ECT from %pI4 " |
160 | "with TOS=%#x\n" , |
161 | &((struct iphdr *)oiph)->saddr, |
162 | ((struct iphdr *)oiph)->tos); |
163 | else |
164 | net_info_ratelimited("non-ECT from %pI6\n" , |
165 | &((struct ipv6hdr *)oiph)->saddr); |
166 | } |
167 | if (err > 1) { |
168 | ++bareudp->dev->stats.rx_frame_errors; |
169 | ++bareudp->dev->stats.rx_errors; |
170 | goto drop; |
171 | } |
172 | } |
173 | |
174 | len = skb->len; |
175 | err = gro_cells_receive(gcells: &bareudp->gro_cells, skb); |
176 | if (likely(err == NET_RX_SUCCESS)) |
177 | dev_sw_netstats_rx_add(dev: bareudp->dev, len); |
178 | |
179 | return 0; |
180 | drop: |
181 | /* Consume bad packet */ |
182 | kfree_skb(skb); |
183 | |
184 | return 0; |
185 | } |
186 | |
187 | static int bareudp_err_lookup(struct sock *sk, struct sk_buff *skb) |
188 | { |
189 | return 0; |
190 | } |
191 | |
192 | static int bareudp_init(struct net_device *dev) |
193 | { |
194 | struct bareudp_dev *bareudp = netdev_priv(dev); |
195 | int err; |
196 | |
197 | err = gro_cells_init(gcells: &bareudp->gro_cells, dev); |
198 | if (err) |
199 | return err; |
200 | |
201 | return 0; |
202 | } |
203 | |
204 | static void bareudp_uninit(struct net_device *dev) |
205 | { |
206 | struct bareudp_dev *bareudp = netdev_priv(dev); |
207 | |
208 | gro_cells_destroy(gcells: &bareudp->gro_cells); |
209 | } |
210 | |
211 | static struct socket *bareudp_create_sock(struct net *net, __be16 port) |
212 | { |
213 | struct udp_port_cfg udp_conf; |
214 | struct socket *sock; |
215 | int err; |
216 | |
217 | memset(&udp_conf, 0, sizeof(udp_conf)); |
218 | |
219 | if (ipv6_mod_enabled()) |
220 | udp_conf.family = AF_INET6; |
221 | else |
222 | udp_conf.family = AF_INET; |
223 | |
224 | udp_conf.local_udp_port = port; |
225 | /* Open UDP socket */ |
226 | err = udp_sock_create(net, cfg: &udp_conf, sockp: &sock); |
227 | if (err < 0) |
228 | return ERR_PTR(error: err); |
229 | |
230 | udp_allow_gso(sk: sock->sk); |
231 | return sock; |
232 | } |
233 | |
234 | /* Create new listen socket if needed */ |
235 | static int bareudp_socket_create(struct bareudp_dev *bareudp, __be16 port) |
236 | { |
237 | struct udp_tunnel_sock_cfg tunnel_cfg; |
238 | struct socket *sock; |
239 | |
240 | sock = bareudp_create_sock(net: bareudp->net, port); |
241 | if (IS_ERR(ptr: sock)) |
242 | return PTR_ERR(ptr: sock); |
243 | |
244 | /* Mark socket as an encapsulation socket */ |
245 | memset(&tunnel_cfg, 0, sizeof(tunnel_cfg)); |
246 | tunnel_cfg.sk_user_data = bareudp; |
247 | tunnel_cfg.encap_type = 1; |
248 | tunnel_cfg.encap_rcv = bareudp_udp_encap_recv; |
249 | tunnel_cfg.encap_err_lookup = bareudp_err_lookup; |
250 | tunnel_cfg.encap_destroy = NULL; |
251 | setup_udp_tunnel_sock(net: bareudp->net, sock, sock_cfg: &tunnel_cfg); |
252 | |
253 | rcu_assign_pointer(bareudp->sock, sock); |
254 | return 0; |
255 | } |
256 | |
257 | static int bareudp_open(struct net_device *dev) |
258 | { |
259 | struct bareudp_dev *bareudp = netdev_priv(dev); |
260 | int ret = 0; |
261 | |
262 | ret = bareudp_socket_create(bareudp, port: bareudp->port); |
263 | return ret; |
264 | } |
265 | |
266 | static void bareudp_sock_release(struct bareudp_dev *bareudp) |
267 | { |
268 | struct socket *sock; |
269 | |
270 | sock = bareudp->sock; |
271 | rcu_assign_pointer(bareudp->sock, NULL); |
272 | synchronize_net(); |
273 | udp_tunnel_sock_release(sock); |
274 | } |
275 | |
276 | static int bareudp_stop(struct net_device *dev) |
277 | { |
278 | struct bareudp_dev *bareudp = netdev_priv(dev); |
279 | |
280 | bareudp_sock_release(bareudp); |
281 | return 0; |
282 | } |
283 | |
284 | static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
285 | struct bareudp_dev *bareudp, |
286 | const struct ip_tunnel_info *info) |
287 | { |
288 | bool xnet = !net_eq(net1: bareudp->net, net2: dev_net(dev: bareudp->dev)); |
289 | bool use_cache = ip_tunnel_dst_cache_usable(skb, info); |
290 | struct socket *sock = rcu_dereference(bareudp->sock); |
291 | bool udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM); |
292 | const struct ip_tunnel_key *key = &info->key; |
293 | struct rtable *rt; |
294 | __be16 sport, df; |
295 | int min_headroom; |
296 | __u8 tos, ttl; |
297 | __be32 saddr; |
298 | int err; |
299 | |
300 | if (!sock) |
301 | return -ESHUTDOWN; |
302 | |
303 | sport = udp_flow_src_port(net: bareudp->net, skb, |
304 | min: bareudp->sport_min, USHRT_MAX, |
305 | use_eth: true); |
306 | rt = udp_tunnel_dst_lookup(skb, dev, net: bareudp->net, oif: 0, saddr: &saddr, key: &info->key, |
307 | sport, dport: bareudp->port, tos: key->tos, |
308 | dst_cache: use_cache ? |
309 | (struct dst_cache *)&info->dst_cache : NULL); |
310 | |
311 | if (IS_ERR(ptr: rt)) |
312 | return PTR_ERR(ptr: rt); |
313 | |
314 | skb_tunnel_check_pmtu(skb, encap_dst: &rt->dst, |
315 | BAREUDP_IPV4_HLEN + info->options_len, reply: false); |
316 | |
317 | tos = ip_tunnel_ecn_encap(tos: key->tos, iph: ip_hdr(skb), skb); |
318 | ttl = key->ttl; |
319 | df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; |
320 | skb_scrub_packet(skb, xnet); |
321 | |
322 | err = -ENOSPC; |
323 | if (!skb_pull(skb, len: skb_network_offset(skb))) |
324 | goto free_dst; |
325 | |
326 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len + |
327 | BAREUDP_BASE_HLEN + info->options_len + sizeof(struct iphdr); |
328 | |
329 | err = skb_cow_head(skb, headroom: min_headroom); |
330 | if (unlikely(err)) |
331 | goto free_dst; |
332 | |
333 | err = udp_tunnel_handle_offloads(skb, udp_csum: udp_sum); |
334 | if (err) |
335 | goto free_dst; |
336 | |
337 | skb_set_inner_protocol(skb, protocol: bareudp->ethertype); |
338 | udp_tunnel_xmit_skb(rt, sk: sock->sk, skb, src: saddr, dst: info->key.u.ipv4.dst, |
339 | tos, ttl, df, src_port: sport, dst_port: bareudp->port, |
340 | xnet: !net_eq(net1: bareudp->net, net2: dev_net(dev: bareudp->dev)), |
341 | nocheck: !(info->key.tun_flags & TUNNEL_CSUM)); |
342 | return 0; |
343 | |
344 | free_dst: |
345 | dst_release(dst: &rt->dst); |
346 | return err; |
347 | } |
348 | |
349 | static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
350 | struct bareudp_dev *bareudp, |
351 | const struct ip_tunnel_info *info) |
352 | { |
353 | bool xnet = !net_eq(net1: bareudp->net, net2: dev_net(dev: bareudp->dev)); |
354 | bool use_cache = ip_tunnel_dst_cache_usable(skb, info); |
355 | struct socket *sock = rcu_dereference(bareudp->sock); |
356 | bool udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM); |
357 | const struct ip_tunnel_key *key = &info->key; |
358 | struct dst_entry *dst = NULL; |
359 | struct in6_addr saddr, daddr; |
360 | int min_headroom; |
361 | __u8 prio, ttl; |
362 | __be16 sport; |
363 | int err; |
364 | |
365 | if (!sock) |
366 | return -ESHUTDOWN; |
367 | |
368 | sport = udp_flow_src_port(net: bareudp->net, skb, |
369 | min: bareudp->sport_min, USHRT_MAX, |
370 | use_eth: true); |
371 | dst = udp_tunnel6_dst_lookup(skb, dev, net: bareudp->net, sock, oif: 0, saddr: &saddr, |
372 | key, sport, dport: bareudp->port, dsfield: key->tos, |
373 | dst_cache: use_cache ? |
374 | (struct dst_cache *) &info->dst_cache : NULL); |
375 | if (IS_ERR(ptr: dst)) |
376 | return PTR_ERR(ptr: dst); |
377 | |
378 | skb_tunnel_check_pmtu(skb, encap_dst: dst, BAREUDP_IPV6_HLEN + info->options_len, |
379 | reply: false); |
380 | |
381 | prio = ip_tunnel_ecn_encap(tos: key->tos, iph: ip_hdr(skb), skb); |
382 | ttl = key->ttl; |
383 | |
384 | skb_scrub_packet(skb, xnet); |
385 | |
386 | err = -ENOSPC; |
387 | if (!skb_pull(skb, len: skb_network_offset(skb))) |
388 | goto free_dst; |
389 | |
390 | min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len + |
391 | BAREUDP_BASE_HLEN + info->options_len + sizeof(struct ipv6hdr); |
392 | |
393 | err = skb_cow_head(skb, headroom: min_headroom); |
394 | if (unlikely(err)) |
395 | goto free_dst; |
396 | |
397 | err = udp_tunnel_handle_offloads(skb, udp_csum: udp_sum); |
398 | if (err) |
399 | goto free_dst; |
400 | |
401 | daddr = info->key.u.ipv6.dst; |
402 | udp_tunnel6_xmit_skb(dst, sk: sock->sk, skb, dev, |
403 | saddr: &saddr, daddr: &daddr, prio, ttl, |
404 | label: info->key.label, src_port: sport, dst_port: bareudp->port, |
405 | nocheck: !(info->key.tun_flags & TUNNEL_CSUM)); |
406 | return 0; |
407 | |
408 | free_dst: |
409 | dst_release(dst); |
410 | return err; |
411 | } |
412 | |
413 | static bool bareudp_proto_valid(struct bareudp_dev *bareudp, __be16 proto) |
414 | { |
415 | if (bareudp->ethertype == proto) |
416 | return true; |
417 | |
418 | if (!bareudp->multi_proto_mode) |
419 | return false; |
420 | |
421 | if (bareudp->ethertype == htons(ETH_P_MPLS_UC) && |
422 | proto == htons(ETH_P_MPLS_MC)) |
423 | return true; |
424 | |
425 | if (bareudp->ethertype == htons(ETH_P_IP) && |
426 | proto == htons(ETH_P_IPV6)) |
427 | return true; |
428 | |
429 | return false; |
430 | } |
431 | |
432 | static netdev_tx_t bareudp_xmit(struct sk_buff *skb, struct net_device *dev) |
433 | { |
434 | struct bareudp_dev *bareudp = netdev_priv(dev); |
435 | struct ip_tunnel_info *info = NULL; |
436 | int err; |
437 | |
438 | if (!bareudp_proto_valid(bareudp, proto: skb->protocol)) { |
439 | err = -EINVAL; |
440 | goto tx_error; |
441 | } |
442 | |
443 | info = skb_tunnel_info(skb); |
444 | if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) { |
445 | err = -EINVAL; |
446 | goto tx_error; |
447 | } |
448 | |
449 | rcu_read_lock(); |
450 | if (ipv6_mod_enabled() && info->mode & IP_TUNNEL_INFO_IPV6) |
451 | err = bareudp6_xmit_skb(skb, dev, bareudp, info); |
452 | else |
453 | err = bareudp_xmit_skb(skb, dev, bareudp, info); |
454 | |
455 | rcu_read_unlock(); |
456 | |
457 | if (likely(!err)) |
458 | return NETDEV_TX_OK; |
459 | tx_error: |
460 | dev_kfree_skb(skb); |
461 | |
462 | if (err == -ELOOP) |
463 | dev->stats.collisions++; |
464 | else if (err == -ENETUNREACH) |
465 | dev->stats.tx_carrier_errors++; |
466 | |
467 | dev->stats.tx_errors++; |
468 | return NETDEV_TX_OK; |
469 | } |
470 | |
471 | static int bareudp_fill_metadata_dst(struct net_device *dev, |
472 | struct sk_buff *skb) |
473 | { |
474 | struct ip_tunnel_info *info = skb_tunnel_info(skb); |
475 | struct bareudp_dev *bareudp = netdev_priv(dev); |
476 | bool use_cache; |
477 | __be16 sport; |
478 | |
479 | use_cache = ip_tunnel_dst_cache_usable(skb, info); |
480 | sport = udp_flow_src_port(net: bareudp->net, skb, |
481 | min: bareudp->sport_min, USHRT_MAX, |
482 | use_eth: true); |
483 | |
484 | if (!ipv6_mod_enabled() || ip_tunnel_info_af(tun_info: info) == AF_INET) { |
485 | struct rtable *rt; |
486 | __be32 saddr; |
487 | |
488 | rt = udp_tunnel_dst_lookup(skb, dev, net: bareudp->net, oif: 0, saddr: &saddr, |
489 | key: &info->key, sport, dport: bareudp->port, |
490 | tos: info->key.tos, |
491 | dst_cache: use_cache ? &info->dst_cache : NULL); |
492 | if (IS_ERR(ptr: rt)) |
493 | return PTR_ERR(ptr: rt); |
494 | |
495 | ip_rt_put(rt); |
496 | info->key.u.ipv4.src = saddr; |
497 | } else if (ip_tunnel_info_af(tun_info: info) == AF_INET6) { |
498 | struct dst_entry *dst; |
499 | struct in6_addr saddr; |
500 | struct socket *sock = rcu_dereference(bareudp->sock); |
501 | |
502 | dst = udp_tunnel6_dst_lookup(skb, dev, net: bareudp->net, sock, |
503 | oif: 0, saddr: &saddr, key: &info->key, |
504 | sport, dport: bareudp->port, dsfield: info->key.tos, |
505 | dst_cache: use_cache ? &info->dst_cache : NULL); |
506 | if (IS_ERR(ptr: dst)) |
507 | return PTR_ERR(ptr: dst); |
508 | |
509 | dst_release(dst); |
510 | info->key.u.ipv6.src = saddr; |
511 | } else { |
512 | return -EINVAL; |
513 | } |
514 | |
515 | info->key.tp_src = sport; |
516 | info->key.tp_dst = bareudp->port; |
517 | return 0; |
518 | } |
519 | |
520 | static const struct net_device_ops bareudp_netdev_ops = { |
521 | .ndo_init = bareudp_init, |
522 | .ndo_uninit = bareudp_uninit, |
523 | .ndo_open = bareudp_open, |
524 | .ndo_stop = bareudp_stop, |
525 | .ndo_start_xmit = bareudp_xmit, |
526 | .ndo_fill_metadata_dst = bareudp_fill_metadata_dst, |
527 | }; |
528 | |
529 | static const struct nla_policy bareudp_policy[IFLA_BAREUDP_MAX + 1] = { |
530 | [IFLA_BAREUDP_PORT] = { .type = NLA_U16 }, |
531 | [IFLA_BAREUDP_ETHERTYPE] = { .type = NLA_U16 }, |
532 | [IFLA_BAREUDP_SRCPORT_MIN] = { .type = NLA_U16 }, |
533 | [IFLA_BAREUDP_MULTIPROTO_MODE] = { .type = NLA_FLAG }, |
534 | }; |
535 | |
536 | /* Info for udev, that this is a virtual tunnel endpoint */ |
537 | static const struct device_type bareudp_type = { |
538 | .name = "bareudp" , |
539 | }; |
540 | |
541 | /* Initialize the device structure. */ |
542 | static void bareudp_setup(struct net_device *dev) |
543 | { |
544 | dev->netdev_ops = &bareudp_netdev_ops; |
545 | dev->needs_free_netdev = true; |
546 | SET_NETDEV_DEVTYPE(dev, &bareudp_type); |
547 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; |
548 | dev->features |= NETIF_F_RXCSUM; |
549 | dev->features |= NETIF_F_LLTX; |
550 | dev->features |= NETIF_F_GSO_SOFTWARE; |
551 | dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; |
552 | dev->hw_features |= NETIF_F_RXCSUM; |
553 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; |
554 | dev->hard_header_len = 0; |
555 | dev->addr_len = 0; |
556 | dev->mtu = ETH_DATA_LEN; |
557 | dev->min_mtu = IPV4_MIN_MTU; |
558 | dev->max_mtu = IP_MAX_MTU - BAREUDP_BASE_HLEN; |
559 | dev->type = ARPHRD_NONE; |
560 | netif_keep_dst(dev); |
561 | dev->priv_flags |= IFF_NO_QUEUE; |
562 | dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; |
563 | dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; |
564 | } |
565 | |
566 | static int bareudp_validate(struct nlattr *tb[], struct nlattr *data[], |
567 | struct netlink_ext_ack *extack) |
568 | { |
569 | if (!data) { |
570 | NL_SET_ERR_MSG(extack, |
571 | "Not enough attributes provided to perform the operation" ); |
572 | return -EINVAL; |
573 | } |
574 | return 0; |
575 | } |
576 | |
577 | static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf, |
578 | struct netlink_ext_ack *extack) |
579 | { |
580 | memset(conf, 0, sizeof(*conf)); |
581 | |
582 | if (!data[IFLA_BAREUDP_PORT]) { |
583 | NL_SET_ERR_MSG(extack, "port not specified" ); |
584 | return -EINVAL; |
585 | } |
586 | if (!data[IFLA_BAREUDP_ETHERTYPE]) { |
587 | NL_SET_ERR_MSG(extack, "ethertype not specified" ); |
588 | return -EINVAL; |
589 | } |
590 | |
591 | conf->port = nla_get_u16(nla: data[IFLA_BAREUDP_PORT]); |
592 | conf->ethertype = nla_get_u16(nla: data[IFLA_BAREUDP_ETHERTYPE]); |
593 | |
594 | if (data[IFLA_BAREUDP_SRCPORT_MIN]) |
595 | conf->sport_min = nla_get_u16(nla: data[IFLA_BAREUDP_SRCPORT_MIN]); |
596 | |
597 | if (data[IFLA_BAREUDP_MULTIPROTO_MODE]) |
598 | conf->multi_proto_mode = true; |
599 | |
600 | return 0; |
601 | } |
602 | |
603 | static struct bareudp_dev *bareudp_find_dev(struct bareudp_net *bn, |
604 | const struct bareudp_conf *conf) |
605 | { |
606 | struct bareudp_dev *bareudp, *t = NULL; |
607 | |
608 | list_for_each_entry(bareudp, &bn->bareudp_list, next) { |
609 | if (conf->port == bareudp->port) |
610 | t = bareudp; |
611 | } |
612 | return t; |
613 | } |
614 | |
615 | static int bareudp_configure(struct net *net, struct net_device *dev, |
616 | struct bareudp_conf *conf, |
617 | struct netlink_ext_ack *extack) |
618 | { |
619 | struct bareudp_net *bn = net_generic(net, id: bareudp_net_id); |
620 | struct bareudp_dev *t, *bareudp = netdev_priv(dev); |
621 | int err; |
622 | |
623 | bareudp->net = net; |
624 | bareudp->dev = dev; |
625 | t = bareudp_find_dev(bn, conf); |
626 | if (t) { |
627 | NL_SET_ERR_MSG(extack, "Another bareudp device using the same port already exists" ); |
628 | return -EBUSY; |
629 | } |
630 | |
631 | if (conf->multi_proto_mode && |
632 | (conf->ethertype != htons(ETH_P_MPLS_UC) && |
633 | conf->ethertype != htons(ETH_P_IP))) { |
634 | NL_SET_ERR_MSG(extack, "Cannot set multiproto mode for this ethertype (only IPv4 and unicast MPLS are supported)" ); |
635 | return -EINVAL; |
636 | } |
637 | |
638 | bareudp->port = conf->port; |
639 | bareudp->ethertype = conf->ethertype; |
640 | bareudp->sport_min = conf->sport_min; |
641 | bareudp->multi_proto_mode = conf->multi_proto_mode; |
642 | |
643 | err = register_netdevice(dev); |
644 | if (err) |
645 | return err; |
646 | |
647 | list_add(new: &bareudp->next, head: &bn->bareudp_list); |
648 | return 0; |
649 | } |
650 | |
651 | static int bareudp_link_config(struct net_device *dev, |
652 | struct nlattr *tb[]) |
653 | { |
654 | int err; |
655 | |
656 | if (tb[IFLA_MTU]) { |
657 | err = dev_set_mtu(dev, nla_get_u32(nla: tb[IFLA_MTU])); |
658 | if (err) |
659 | return err; |
660 | } |
661 | return 0; |
662 | } |
663 | |
664 | static void bareudp_dellink(struct net_device *dev, struct list_head *head) |
665 | { |
666 | struct bareudp_dev *bareudp = netdev_priv(dev); |
667 | |
668 | list_del(entry: &bareudp->next); |
669 | unregister_netdevice_queue(dev, head); |
670 | } |
671 | |
672 | static int bareudp_newlink(struct net *net, struct net_device *dev, |
673 | struct nlattr *tb[], struct nlattr *data[], |
674 | struct netlink_ext_ack *extack) |
675 | { |
676 | struct bareudp_conf conf; |
677 | int err; |
678 | |
679 | err = bareudp2info(data, conf: &conf, extack); |
680 | if (err) |
681 | return err; |
682 | |
683 | err = bareudp_configure(net, dev, conf: &conf, extack); |
684 | if (err) |
685 | return err; |
686 | |
687 | err = bareudp_link_config(dev, tb); |
688 | if (err) |
689 | goto err_unconfig; |
690 | |
691 | return 0; |
692 | |
693 | err_unconfig: |
694 | bareudp_dellink(dev, NULL); |
695 | return err; |
696 | } |
697 | |
698 | static size_t bareudp_get_size(const struct net_device *dev) |
699 | { |
700 | return nla_total_size(payload: sizeof(__be16)) + /* IFLA_BAREUDP_PORT */ |
701 | nla_total_size(payload: sizeof(__be16)) + /* IFLA_BAREUDP_ETHERTYPE */ |
702 | nla_total_size(payload: sizeof(__u16)) + /* IFLA_BAREUDP_SRCPORT_MIN */ |
703 | nla_total_size(payload: 0) + /* IFLA_BAREUDP_MULTIPROTO_MODE */ |
704 | 0; |
705 | } |
706 | |
707 | static int bareudp_fill_info(struct sk_buff *skb, const struct net_device *dev) |
708 | { |
709 | struct bareudp_dev *bareudp = netdev_priv(dev); |
710 | |
711 | if (nla_put_be16(skb, attrtype: IFLA_BAREUDP_PORT, value: bareudp->port)) |
712 | goto nla_put_failure; |
713 | if (nla_put_be16(skb, attrtype: IFLA_BAREUDP_ETHERTYPE, value: bareudp->ethertype)) |
714 | goto nla_put_failure; |
715 | if (nla_put_u16(skb, attrtype: IFLA_BAREUDP_SRCPORT_MIN, value: bareudp->sport_min)) |
716 | goto nla_put_failure; |
717 | if (bareudp->multi_proto_mode && |
718 | nla_put_flag(skb, attrtype: IFLA_BAREUDP_MULTIPROTO_MODE)) |
719 | goto nla_put_failure; |
720 | |
721 | return 0; |
722 | |
723 | nla_put_failure: |
724 | return -EMSGSIZE; |
725 | } |
726 | |
727 | static struct rtnl_link_ops bareudp_link_ops __read_mostly = { |
728 | .kind = "bareudp" , |
729 | .maxtype = IFLA_BAREUDP_MAX, |
730 | .policy = bareudp_policy, |
731 | .priv_size = sizeof(struct bareudp_dev), |
732 | .setup = bareudp_setup, |
733 | .validate = bareudp_validate, |
734 | .newlink = bareudp_newlink, |
735 | .dellink = bareudp_dellink, |
736 | .get_size = bareudp_get_size, |
737 | .fill_info = bareudp_fill_info, |
738 | }; |
739 | |
740 | static __net_init int bareudp_init_net(struct net *net) |
741 | { |
742 | struct bareudp_net *bn = net_generic(net, id: bareudp_net_id); |
743 | |
744 | INIT_LIST_HEAD(list: &bn->bareudp_list); |
745 | return 0; |
746 | } |
747 | |
748 | static void bareudp_destroy_tunnels(struct net *net, struct list_head *head) |
749 | { |
750 | struct bareudp_net *bn = net_generic(net, id: bareudp_net_id); |
751 | struct bareudp_dev *bareudp, *next; |
752 | |
753 | list_for_each_entry_safe(bareudp, next, &bn->bareudp_list, next) |
754 | unregister_netdevice_queue(dev: bareudp->dev, head); |
755 | } |
756 | |
757 | static void __net_exit bareudp_exit_batch_rtnl(struct list_head *net_list, |
758 | struct list_head *dev_kill_list) |
759 | { |
760 | struct net *net; |
761 | |
762 | list_for_each_entry(net, net_list, exit_list) |
763 | bareudp_destroy_tunnels(net, head: dev_kill_list); |
764 | } |
765 | |
766 | static struct pernet_operations bareudp_net_ops = { |
767 | .init = bareudp_init_net, |
768 | .exit_batch_rtnl = bareudp_exit_batch_rtnl, |
769 | .id = &bareudp_net_id, |
770 | .size = sizeof(struct bareudp_net), |
771 | }; |
772 | |
773 | static int __init bareudp_init_module(void) |
774 | { |
775 | int rc; |
776 | |
777 | rc = register_pernet_subsys(&bareudp_net_ops); |
778 | if (rc) |
779 | goto out1; |
780 | |
781 | rc = rtnl_link_register(ops: &bareudp_link_ops); |
782 | if (rc) |
783 | goto out2; |
784 | |
785 | return 0; |
786 | out2: |
787 | unregister_pernet_subsys(&bareudp_net_ops); |
788 | out1: |
789 | return rc; |
790 | } |
791 | late_initcall(bareudp_init_module); |
792 | |
793 | static void __exit bareudp_cleanup_module(void) |
794 | { |
795 | rtnl_link_unregister(ops: &bareudp_link_ops); |
796 | unregister_pernet_subsys(&bareudp_net_ops); |
797 | } |
798 | module_exit(bareudp_cleanup_module); |
799 | |
800 | MODULE_ALIAS_RTNL_LINK("bareudp" ); |
801 | MODULE_LICENSE("GPL" ); |
802 | MODULE_AUTHOR("Martin Varghese <martin.varghese@nokia.com>" ); |
803 | MODULE_DESCRIPTION("Interface driver for UDP encapsulated traffic" ); |
804 | |