Blame view

net/tipc/udp_media.c 21.2 KB
d0f91938b   Erik Hugne   tipc: add ip/udp ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  /* net/tipc/udp_media.c: IP bearer support for TIPC
   *
   * Copyright (c) 2015, Ericsson AB
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   * 3. Neither the names of the copyright holders nor the names of its
   *    contributors may be used to endorse or promote products derived from
   *    this software without specific prior written permission.
   *
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGE.
   */
  
  #include <linux/socket.h>
  #include <linux/ip.h>
  #include <linux/udp.h>
  #include <linux/inet.h>
  #include <linux/inetdevice.h>
  #include <linux/igmp.h>
  #include <linux/kernel.h>
  #include <linux/workqueue.h>
  #include <linux/list.h>
  #include <net/sock.h>
  #include <net/ip.h>
  #include <net/udp_tunnel.h>
3616d08bc   David Ahern   ipv6: Move ipv6 s...
47
  #include <net/ipv6_stubs.h>
d0f91938b   Erik Hugne   tipc: add ip/udp ...
48
49
  #include <linux/tipc_netlink.h>
  #include "core.h"
52dfae5c8   Jon Maloy   tipc: obtain node...
50
51
  #include "addr.h"
  #include "net.h"
d0f91938b   Erik Hugne   tipc: add ip/udp ...
52
  #include "bearer.h"
49cc66eae   Richard Alpe   tipc: move netlin...
53
  #include "netlink.h"
ef20cd4dd   Richard Alpe   tipc: introduce U...
54
  #include "msg.h"
5f3666e83   Wang Hai   net: tipc: Supply...
55
  #include "udp_media.h"
d0f91938b   Erik Hugne   tipc: add ip/udp ...
56
57
58
  
  /* IANA assigned UDP port */
  #define UDP_PORT_DEFAULT	6118
9bd160bfa   Richard Alpe   tipc: make sure I...
59
  #define UDP_MIN_HEADROOM        48
e53567948   Jon Paul Maloy   tipc: conditional...
60

d0f91938b   Erik Hugne   tipc: add ip/udp ...
61
62
63
64
65
66
67
68
  /**
   * struct udp_media_addr - IP/UDP addressing information
   *
   * This is the bearer level originating address used in neighbor discovery
   * messages, and all fields should be in network byte order
   */
  struct udp_media_addr {
  	__be16	proto;
bc3a334cc   Richard Alpe   tipc: rename udp_...
69
  	__be16	port;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
70
71
72
73
74
  	union {
  		struct in_addr ipv4;
  		struct in6_addr ipv6;
  	};
  };
ef20cd4dd   Richard Alpe   tipc: introduce U...
75
76
77
  /* struct udp_replicast - container for UDP remote addresses */
  struct udp_replicast {
  	struct udp_media_addr addr;
e9c1a7932   Xin Long   tipc: add dst_cac...
78
  	struct dst_cache dst_cache;
ef20cd4dd   Richard Alpe   tipc: introduce U...
79
80
81
  	struct rcu_head rcu;
  	struct list_head list;
  };
d0f91938b   Erik Hugne   tipc: add ip/udp ...
82
83
84
85
86
87
88
89
90
91
92
93
  /**
   * struct udp_bearer - ip/udp bearer data structure
   * @bearer:	associated generic tipc bearer
   * @ubsock:	bearer associated socket
   * @ifindex:	local address scope
   * @work:	used to schedule deferred work on a bearer
   */
  struct udp_bearer {
  	struct tipc_bearer __rcu *bearer;
  	struct socket *ubsock;
  	u32 ifindex;
  	struct work_struct work;
ef20cd4dd   Richard Alpe   tipc: introduce U...
94
  	struct udp_replicast rcast;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
95
  };
1ca73e3fa   Richard Alpe   tipc: refactor mu...
96
97
98
99
100
101
102
103
104
105
  static int tipc_udp_is_mcast_addr(struct udp_media_addr *addr)
  {
  	if (ntohs(addr->proto) == ETH_P_IP)
  		return ipv4_is_multicast(addr->ipv4.s_addr);
  #if IS_ENABLED(CONFIG_IPV6)
  	else
  		return ipv6_addr_is_multicast(&addr->ipv6);
  #endif
  	return 0;
  }
d0f91938b   Erik Hugne   tipc: add ip/udp ...
106
107
108
109
110
111
112
  /* udp_media_addr_set - convert a ip/udp address to a TIPC media address */
  static void tipc_udp_media_addr_set(struct tipc_media_addr *addr,
  				    struct udp_media_addr *ua)
  {
  	memset(addr, 0, sizeof(struct tipc_media_addr));
  	addr->media_id = TIPC_MEDIA_TYPE_UDP;
  	memcpy(addr->value, ua, sizeof(struct udp_media_addr));
1ca73e3fa   Richard Alpe   tipc: refactor mu...
113
114
  
  	if (tipc_udp_is_mcast_addr(ua))
9999974a8   Jon Paul Maloy   tipc: add functio...
115
  		addr->broadcast = TIPC_BROADCAST_SUPPORT;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
116
117
118
119
120
121
122
123
  }
  
  /* tipc_udp_addr2str - convert ip/udp address to string */
  static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size)
  {
  	struct udp_media_addr *ua = (struct udp_media_addr *)&a->value;
  
  	if (ntohs(ua->proto) == ETH_P_IP)
bc3a334cc   Richard Alpe   tipc: rename udp_...
124
  		snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->port));
d0f91938b   Erik Hugne   tipc: add ip/udp ...
125
  	else if (ntohs(ua->proto) == ETH_P_IPV6)
bc3a334cc   Richard Alpe   tipc: rename udp_...
126
  		snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->port));
d0f91938b   Erik Hugne   tipc: add ip/udp ...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  	else
  		pr_err("Invalid UDP media address
  ");
  	return 0;
  }
  
  /* tipc_udp_msg2addr - extract an ip/udp address from a TIPC ndisc message */
  static int tipc_udp_msg2addr(struct tipc_bearer *b, struct tipc_media_addr *a,
  			     char *msg)
  {
  	struct udp_media_addr *ua;
  
  	ua = (struct udp_media_addr *) (msg + TIPC_MEDIA_ADDR_OFFSET);
  	if (msg[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_UDP)
  		return -EINVAL;
  	tipc_udp_media_addr_set(a, ua);
  	return 0;
  }
  
  /* tipc_udp_addr2msg - write an ip/udp address to a TIPC ndisc message */
  static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a)
  {
  	memset(msg, 0, TIPC_MEDIA_INFO_SIZE);
  	msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_UDP;
  	memcpy(msg + TIPC_MEDIA_ADDR_OFFSET, a->value,
  	       sizeof(struct udp_media_addr));
  	return 0;
  }
  
  /* tipc_send_msg - enqueue a send request */
ce984da36   Richard Alpe   tipc: split UDP s...
157
158
  static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
  			 struct udp_bearer *ub, struct udp_media_addr *src,
e9c1a7932   Xin Long   tipc: add dst_cac...
159
  			 struct udp_media_addr *dst, struct dst_cache *cache)
d0f91938b   Erik Hugne   tipc: add ip/udp ...
160
  {
137881748   Eric Dumazet   tipc: block BH be...
161
  	struct dst_entry *ndst;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
162
  	int ttl, err = 0;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
163

137881748   Eric Dumazet   tipc: block BH be...
164
165
  	local_bh_disable();
  	ndst = dst_cache_get(cache);
4fee6be81   Erik Hugne   tipc: sparse: fix...
166
  	if (dst->proto == htons(ETH_P_IP)) {
e9c1a7932   Xin Long   tipc: add dst_cac...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  		struct rtable *rt = (struct rtable *)ndst;
  
  		if (!rt) {
  			struct flowi4 fl = {
  				.daddr = dst->ipv4.s_addr,
  				.saddr = src->ipv4.s_addr,
  				.flowi4_mark = skb->mark,
  				.flowi4_proto = IPPROTO_UDP
  			};
  			rt = ip_route_output_key(net, &fl);
  			if (IS_ERR(rt)) {
  				err = PTR_ERR(rt);
  				goto tx_error;
  			}
  			dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
182
  		}
9b3009604   Richard Alpe   tipc: add net dev...
183

d0f91938b   Erik Hugne   tipc: add ip/udp ...
184
  		ttl = ip4_dst_hoplimit(&rt->dst);
039f50629   Pravin B Shelar   ip_tunnel: Move s...
185
  		udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
bc3a334cc   Richard Alpe   tipc: rename udp_...
186
187
  				    dst->ipv4.s_addr, 0, ttl, 0, src->port,
  				    dst->port, false, true);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
188
189
  #if IS_ENABLED(CONFIG_IPV6)
  	} else {
e9c1a7932   Xin Long   tipc: add dst_cac...
190
191
192
193
194
195
196
  		if (!ndst) {
  			struct flowi6 fl6 = {
  				.flowi6_oif = ub->ifindex,
  				.daddr = dst->ipv6,
  				.saddr = src->ipv6,
  				.flowi6_proto = IPPROTO_UDP
  			};
6c8991f41   Sabrina Dubroca   net: ipv6_stub: u...
197
198
199
200
201
  			ndst = ipv6_stub->ipv6_dst_lookup_flow(net,
  							       ub->ubsock->sk,
  							       &fl6, NULL);
  			if (IS_ERR(ndst)) {
  				err = PTR_ERR(ndst);
e9c1a7932   Xin Long   tipc: add dst_cac...
202
  				goto tx_error;
6c8991f41   Sabrina Dubroca   net: ipv6_stub: u...
203
  			}
e9c1a7932   Xin Long   tipc: add dst_cac...
204
205
  			dst_cache_set_ip6(cache, ndst, &fl6.saddr);
  		}
d0f91938b   Erik Hugne   tipc: add ip/udp ...
206
  		ttl = ip6_dst_hoplimit(ndst);
c3bcde026   Xin Long   tipc: pass tunnel...
207
208
209
  		err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
  					   &src->ipv6, &dst->ipv6, 0, ttl, 0,
  					   src->port, dst->port, false);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
210
211
  #endif
  	}
137881748   Eric Dumazet   tipc: block BH be...
212
  	local_bh_enable();
d0f91938b   Erik Hugne   tipc: add ip/udp ...
213
214
215
  	return err;
  
  tx_error:
137881748   Eric Dumazet   tipc: block BH be...
216
  	local_bh_enable();
7214bcf87   Jon Paul Maloy   tipc: eliminate r...
217
  	kfree_skb(skb);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
218
219
  	return err;
  }
ce984da36   Richard Alpe   tipc: split UDP s...
220
221
222
223
224
225
  static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
  			     struct tipc_bearer *b,
  			     struct tipc_media_addr *addr)
  {
  	struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
  	struct udp_media_addr *dst = (struct udp_media_addr *)&addr->value;
ef20cd4dd   Richard Alpe   tipc: introduce U...
226
  	struct udp_replicast *rcast;
ce984da36   Richard Alpe   tipc: split UDP s...
227
228
229
230
231
232
  	struct udp_bearer *ub;
  	int err = 0;
  
  	if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
  		err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
  		if (err)
ef20cd4dd   Richard Alpe   tipc: introduce U...
233
  			goto out;
ce984da36   Richard Alpe   tipc: split UDP s...
234
235
236
  	}
  
  	skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
30a4616c1   Xin Long   tipc: use rcu der...
237
  	ub = rcu_dereference(b->media_ptr);
ce984da36   Richard Alpe   tipc: split UDP s...
238
239
  	if (!ub) {
  		err = -ENODEV;
ef20cd4dd   Richard Alpe   tipc: introduce U...
240
  		goto out;
ce984da36   Richard Alpe   tipc: split UDP s...
241
  	}
9999974a8   Jon Paul Maloy   tipc: add functio...
242
  	if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
e9c1a7932   Xin Long   tipc: add dst_cac...
243
244
  		return tipc_udp_xmit(net, skb, ub, src, dst,
  				     &ub->rcast.dst_cache);
ce984da36   Richard Alpe   tipc: split UDP s...
245

ef20cd4dd   Richard Alpe   tipc: introduce U...
246
247
248
249
250
251
252
253
254
  	/* Replicast, send an skb to each configured IP address */
  	list_for_each_entry_rcu(rcast, &ub->rcast.list, list) {
  		struct sk_buff *_skb;
  
  		_skb = pskb_copy(skb, GFP_ATOMIC);
  		if (!_skb) {
  			err = -ENOMEM;
  			goto out;
  		}
e9c1a7932   Xin Long   tipc: add dst_cac...
255
256
  		err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr,
  				    &rcast->dst_cache);
acb4a33e9   Cong Wang   tipc: fix a doubl...
257
  		if (err)
ef20cd4dd   Richard Alpe   tipc: introduce U...
258
  			goto out;
ef20cd4dd   Richard Alpe   tipc: introduce U...
259
260
261
  	}
  	err = 0;
  out:
ce984da36   Richard Alpe   tipc: split UDP s...
262
263
264
  	kfree_skb(skb);
  	return err;
  }
c9b64d492   Richard Alpe   tipc: add replica...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
  				   struct udp_media_addr *addr)
  {
  	struct udp_replicast *rcast, *tmp;
  	struct udp_bearer *ub;
  
  	ub = rcu_dereference_rtnl(b->media_ptr);
  	if (!ub) {
  		pr_err_ratelimited("UDP bearer instance not found
  ");
  		return false;
  	}
  
  	list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
  		if (!memcmp(&rcast->addr, addr, sizeof(struct udp_media_addr)))
  			return true;
  	}
  
  	return false;
  }
ef20cd4dd   Richard Alpe   tipc: introduce U...
285
286
287
288
289
290
291
292
293
294
295
296
297
  static int tipc_udp_rcast_add(struct tipc_bearer *b,
  			      struct udp_media_addr *addr)
  {
  	struct udp_replicast *rcast;
  	struct udp_bearer *ub;
  
  	ub = rcu_dereference_rtnl(b->media_ptr);
  	if (!ub)
  		return -ENODEV;
  
  	rcast = kmalloc(sizeof(*rcast), GFP_ATOMIC);
  	if (!rcast)
  		return -ENOMEM;
e9c1a7932   Xin Long   tipc: add dst_cac...
298
299
300
301
  	if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
  		kfree(rcast);
  		return -ENOMEM;
  	}
ef20cd4dd   Richard Alpe   tipc: introduce U...
302
303
304
305
306
307
308
309
310
311
  	memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
  
  	if (ntohs(addr->proto) == ETH_P_IP)
  		pr_info("New replicast peer: %pI4
  ", &rcast->addr.ipv4);
  #if IS_ENABLED(CONFIG_IPV6)
  	else if (ntohs(addr->proto) == ETH_P_IPV6)
  		pr_info("New replicast peer: %pI6
  ", &rcast->addr.ipv6);
  #endif
9999974a8   Jon Paul Maloy   tipc: add functio...
312
  	b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
ef20cd4dd   Richard Alpe   tipc: introduce U...
313
314
315
  	list_add_rcu(&rcast->list, &ub->rcast.list);
  	return 0;
  }
c9b64d492   Richard Alpe   tipc: add replica...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  static int tipc_udp_rcast_disc(struct tipc_bearer *b, struct sk_buff *skb)
  {
  	struct udp_media_addr src = {0};
  	struct udp_media_addr *dst;
  
  	dst = (struct udp_media_addr *)&b->bcast_addr.value;
  	if (tipc_udp_is_mcast_addr(dst))
  		return 0;
  
  	src.port = udp_hdr(skb)->source;
  
  	if (ip_hdr(skb)->version == 4) {
  		struct iphdr *iphdr = ip_hdr(skb);
  
  		src.proto = htons(ETH_P_IP);
  		src.ipv4.s_addr = iphdr->saddr;
  		if (ipv4_is_multicast(iphdr->daddr))
  			return 0;
  #if IS_ENABLED(CONFIG_IPV6)
  	} else if (ip_hdr(skb)->version == 6) {
  		struct ipv6hdr *iphdr = ipv6_hdr(skb);
  
  		src.proto = htons(ETH_P_IPV6);
  		src.ipv6 = iphdr->saddr;
  		if (ipv6_addr_is_multicast(&iphdr->daddr))
  			return 0;
  #endif
  	} else {
  		return 0;
  	}
  
  	if (likely(tipc_udp_is_known_peer(b, &src)))
  		return 0;
  
  	return tipc_udp_rcast_add(b, &src);
  }
d0f91938b   Erik Hugne   tipc: add ip/udp ...
352
353
354
355
356
  /* tipc_udp_recv - read data from bearer socket */
  static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
  {
  	struct udp_bearer *ub;
  	struct tipc_bearer *b;
c9b64d492   Richard Alpe   tipc: add replica...
357
358
  	struct tipc_msg *hdr;
  	int err;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
359
360
361
362
  
  	ub = rcu_dereference_sk_user_data(sk);
  	if (!ub) {
  		pr_err_ratelimited("Failed to get UDP bearer reference");
c9b64d492   Richard Alpe   tipc: add replica...
363
  		goto out;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
364
  	}
d0f91938b   Erik Hugne   tipc: add ip/udp ...
365
  	skb_pull(skb, sizeof(struct udphdr));
c9b64d492   Richard Alpe   tipc: add replica...
366
  	hdr = buf_msg(skb);
4109a2c3b   Eric Dumazet   tipc: tipc_udp_re...
367
  	b = rcu_dereference(ub->bearer);
c9b64d492   Richard Alpe   tipc: add replica...
368
  	if (!b)
4109a2c3b   Eric Dumazet   tipc: tipc_udp_re...
369
  		goto out;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
370

0d051bf93   Jon Paul Maloy   tipc: make bearer...
371
  	if (b && test_bit(0, &b->up)) {
fc1b6d6de   Tuong Lien   tipc: introduce T...
372
  		TIPC_SKB_CB(skb)->flags = 0;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
373
  		tipc_rcv(sock_net(sk), skb, b);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
374
375
  		return 0;
  	}
c9b64d492   Richard Alpe   tipc: add replica...
376
377
378
379
  
  	if (unlikely(msg_user(hdr) == LINK_CONFIG)) {
  		err = tipc_udp_rcast_disc(b, skb);
  		if (err)
4109a2c3b   Eric Dumazet   tipc: tipc_udp_re...
380
  			goto out;
c9b64d492   Richard Alpe   tipc: add replica...
381
  	}
c9b64d492   Richard Alpe   tipc: add replica...
382
  out:
d0f91938b   Erik Hugne   tipc: add ip/udp ...
383
384
385
386
387
388
389
390
391
392
393
  	kfree_skb(skb);
  	return 0;
  }
  
  static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote)
  {
  	int err = 0;
  	struct ip_mreqn mreqn;
  	struct sock *sk = ub->ubsock->sk;
  
  	if (ntohs(remote->proto) == ETH_P_IP) {
d0f91938b   Erik Hugne   tipc: add ip/udp ...
394
395
  		mreqn.imr_multiaddr = remote->ipv4;
  		mreqn.imr_ifindex = ub->ifindex;
54ff9ef36   Marcelo Ricardo Leitner   ipv4, ipv6: kill ...
396
  		err = ip_mc_join_group(sk, &mreqn);
446981e5f   Marcelo Ricardo Leitner   tipc: fix build i...
397
  #if IS_ENABLED(CONFIG_IPV6)
d0f91938b   Erik Hugne   tipc: add ip/udp ...
398
  	} else {
446981e5f   Marcelo Ricardo Leitner   tipc: fix build i...
399
400
401
  		err = ipv6_stub->ipv6_sock_mc_join(sk, ub->ifindex,
  						   &remote->ipv6);
  #endif
d0f91938b   Erik Hugne   tipc: add ip/udp ...
402
403
404
  	}
  	return err;
  }
fdb3accc2   Richard Alpe   tipc: add the abi...
405
406
407
408
409
  static int __tipc_nl_add_udp_addr(struct sk_buff *skb,
  				  struct udp_media_addr *addr, int nla_t)
  {
  	if (ntohs(addr->proto) == ETH_P_IP) {
  		struct sockaddr_in ip4;
730761624   Dan Carpenter   tipc: info leak i...
410
  		memset(&ip4, 0, sizeof(ip4));
fdb3accc2   Richard Alpe   tipc: add the abi...
411
412
413
414
415
416
417
418
419
  		ip4.sin_family = AF_INET;
  		ip4.sin_port = addr->port;
  		ip4.sin_addr.s_addr = addr->ipv4.s_addr;
  		if (nla_put(skb, nla_t, sizeof(ip4), &ip4))
  			return -EMSGSIZE;
  
  #if IS_ENABLED(CONFIG_IPV6)
  	} else if (ntohs(addr->proto) == ETH_P_IPV6) {
  		struct sockaddr_in6 ip6;
730761624   Dan Carpenter   tipc: info leak i...
420
  		memset(&ip6, 0, sizeof(ip6));
fdb3accc2   Richard Alpe   tipc: add the abi...
421
422
423
424
425
426
427
428
429
430
  		ip6.sin6_family = AF_INET6;
  		ip6.sin6_port  = addr->port;
  		memcpy(&ip6.sin6_addr, &addr->ipv6, sizeof(struct in6_addr));
  		if (nla_put(skb, nla_t, sizeof(ip6), &ip6))
  			return -EMSGSIZE;
  #endif
  	}
  
  	return 0;
  }
832629ca5   Richard Alpe   tipc: add UDP rem...
431
432
433
434
435
436
437
438
439
440
441
442
443
  int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb)
  {
  	u32 bid = cb->args[0];
  	u32 skip_cnt = cb->args[1];
  	u32 portid = NETLINK_CB(cb->skb).portid;
  	struct udp_replicast *rcast, *tmp;
  	struct tipc_bearer *b;
  	struct udp_bearer *ub;
  	void *hdr;
  	int err;
  	int i;
  
  	if (!bid && !skip_cnt) {
057af7071   Jiri Pirko   net: tipc: have g...
444
  		struct nlattr **attrs = genl_dumpit_info(cb)->attrs;
832629ca5   Richard Alpe   tipc: add UDP rem...
445
446
  		struct net *net = sock_net(skb->sk);
  		struct nlattr *battrs[TIPC_NLA_BEARER_MAX + 1];
832629ca5   Richard Alpe   tipc: add UDP rem...
447
  		char *bname;
832629ca5   Richard Alpe   tipc: add UDP rem...
448
449
  		if (!attrs[TIPC_NLA_BEARER])
  			return -EINVAL;
8cb081746   Johannes Berg   netlink: make val...
450
451
452
  		err = nla_parse_nested_deprecated(battrs, TIPC_NLA_BEARER_MAX,
  						  attrs[TIPC_NLA_BEARER],
  						  tipc_nl_bearer_policy, NULL);
832629ca5   Richard Alpe   tipc: add UDP rem...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
  		if (err)
  			return err;
  
  		if (!battrs[TIPC_NLA_BEARER_NAME])
  			return -EINVAL;
  
  		bname = nla_data(battrs[TIPC_NLA_BEARER_NAME]);
  
  		rtnl_lock();
  		b = tipc_bearer_find(net, bname);
  		if (!b) {
  			rtnl_unlock();
  			return -EINVAL;
  		}
  		bid = b->identity;
  	} else {
  		struct net *net = sock_net(skb->sk);
  		struct tipc_net *tn = net_generic(net, tipc_net_id);
  
  		rtnl_lock();
  		b = rtnl_dereference(tn->bearer_list[bid]);
  		if (!b) {
  			rtnl_unlock();
  			return -EINVAL;
  		}
  	}
30a4616c1   Xin Long   tipc: use rcu der...
479
  	ub = rtnl_dereference(b->media_ptr);
832629ca5   Richard Alpe   tipc: add UDP rem...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
  	if (!ub) {
  		rtnl_unlock();
  		return -EINVAL;
  	}
  
  	i = 0;
  	list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
  		if (i < skip_cnt)
  			goto count;
  
  		hdr = genlmsg_put(skb, portid, cb->nlh->nlmsg_seq,
  				  &tipc_genl_family, NLM_F_MULTI,
  				  TIPC_NL_BEARER_GET);
  		if (!hdr)
  			goto done;
  
  		err = __tipc_nl_add_udp_addr(skb, &rcast->addr,
  					     TIPC_NLA_UDP_REMOTE);
  		if (err) {
  			genlmsg_cancel(skb, hdr);
  			goto done;
  		}
  		genlmsg_end(skb, hdr);
  count:
  		i++;
  	}
  done:
  	rtnl_unlock();
  	cb->args[0] = bid;
  	cb->args[1] = i;
  
  	return skb->len;
  }
fdb3accc2   Richard Alpe   tipc: add the abi...
513
514
515
516
517
518
  int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b)
  {
  	struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
  	struct udp_media_addr *dst;
  	struct udp_bearer *ub;
  	struct nlattr *nest;
30a4616c1   Xin Long   tipc: use rcu der...
519
  	ub = rtnl_dereference(b->media_ptr);
fdb3accc2   Richard Alpe   tipc: add the abi...
520
521
  	if (!ub)
  		return -ENODEV;
ae0be8de9   Michal Kubecek   netlink: make nla...
522
  	nest = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER_UDP_OPTS);
fdb3accc2   Richard Alpe   tipc: add the abi...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
  	if (!nest)
  		goto msg_full;
  
  	if (__tipc_nl_add_udp_addr(msg->skb, src, TIPC_NLA_UDP_LOCAL))
  		goto msg_full;
  
  	dst = (struct udp_media_addr *)&b->bcast_addr.value;
  	if (__tipc_nl_add_udp_addr(msg->skb, dst, TIPC_NLA_UDP_REMOTE))
  		goto msg_full;
  
  	if (!list_empty(&ub->rcast.list)) {
  		if (nla_put_flag(msg->skb, TIPC_NLA_UDP_MULTI_REMOTEIP))
  			goto msg_full;
  	}
  
  	nla_nest_end(msg->skb, nest);
  	return 0;
  msg_full:
  	nla_nest_cancel(msg->skb, nest);
  	return -EMSGSIZE;
  }
d0f91938b   Erik Hugne   tipc: add ip/udp ...
544
  /**
ba5aa84a2   Richard Alpe   tipc: split UDP n...
545
   * tipc_parse_udp_addr - build udp media address from netlink data
d8141208b   Andrew Lunn   net: tipc: kernel...
546
   * @nla:	netlink attribute containing sockaddr storage aligned address
ba5aa84a2   Richard Alpe   tipc: split UDP n...
547
548
   * @addr:	tipc media address to fill with address, port and protocol type
   * @scope_id:	IPv6 scope id pointer, not NULL indicates it's required
d0f91938b   Erik Hugne   tipc: add ip/udp ...
549
   */
ba5aa84a2   Richard Alpe   tipc: split UDP n...
550
551
552
  
  static int tipc_parse_udp_addr(struct nlattr *nla, struct udp_media_addr *addr,
  			       u32 *scope_id)
d0f91938b   Erik Hugne   tipc: add ip/udp ...
553
  {
ba5aa84a2   Richard Alpe   tipc: split UDP n...
554
  	struct sockaddr_storage sa;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
555

ba5aa84a2   Richard Alpe   tipc: split UDP n...
556
557
558
559
560
561
562
  	nla_memcpy(&sa, nla, sizeof(sa));
  	if (sa.ss_family == AF_INET) {
  		struct sockaddr_in *ip4 = (struct sockaddr_in *)&sa;
  
  		addr->proto = htons(ETH_P_IP);
  		addr->port = ip4->sin_port;
  		addr->ipv4.s_addr = ip4->sin_addr.s_addr;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
563
564
565
  		return 0;
  
  #if IS_ENABLED(CONFIG_IPV6)
ba5aa84a2   Richard Alpe   tipc: split UDP n...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
  	} else if (sa.ss_family == AF_INET6) {
  		struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)&sa;
  
  		addr->proto = htons(ETH_P_IPV6);
  		addr->port = ip6->sin6_port;
  		memcpy(&addr->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
  
  		/* Scope ID is only interesting for local addresses */
  		if (scope_id) {
  			int atype;
  
  			atype = ipv6_addr_type(&ip6->sin6_addr);
  			if (__ipv6_addr_needs_scope_id(atype) &&
  			    !ip6->sin6_scope_id) {
  				return -EINVAL;
  			}
  
  			*scope_id = ip6->sin6_scope_id ? : 0;
  		}
d0f91938b   Erik Hugne   tipc: add ip/udp ...
585
586
587
588
589
  		return 0;
  #endif
  	}
  	return -EADDRNOTAVAIL;
  }
ef20cd4dd   Richard Alpe   tipc: introduce U...
590
591
592
593
594
595
  int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr)
  {
  	int err;
  	struct udp_media_addr addr = {0};
  	struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
  	struct udp_media_addr *dst;
8cb081746   Johannes Berg   netlink: make val...
596
  	if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attr, tipc_nl_udp_policy, NULL))
ef20cd4dd   Richard Alpe   tipc: introduce U...
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
  		return -EINVAL;
  
  	if (!opts[TIPC_NLA_UDP_REMOTE])
  		return -EINVAL;
  
  	err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_REMOTE], &addr, NULL);
  	if (err)
  		return err;
  
  	dst = (struct udp_media_addr *)&b->bcast_addr.value;
  	if (tipc_udp_is_mcast_addr(dst)) {
  		pr_err("Can't add remote ip to TIPC UDP multicast bearer
  ");
  		return -EINVAL;
  	}
c9b64d492   Richard Alpe   tipc: add replica...
612
613
  	if (tipc_udp_is_known_peer(b, &addr))
  		return 0;
ef20cd4dd   Richard Alpe   tipc: introduce U...
614
615
  	return tipc_udp_rcast_add(b, &addr);
  }
d0f91938b   Erik Hugne   tipc: add ip/udp ...
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  /**
   * tipc_udp_enable - callback to create a new udp bearer instance
   * @net:	network namespace
   * @b:		pointer to generic tipc_bearer
   * @attrs:	netlink bearer configuration
   *
   * validate the bearer parameters and initialize the udp bearer
   * rtnl_lock should be held
   */
  static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
  			   struct nlattr *attrs[])
  {
  	int err = -EINVAL;
  	struct udp_bearer *ub;
ef20cd4dd   Richard Alpe   tipc: introduce U...
630
  	struct udp_media_addr remote = {0};
d0f91938b   Erik Hugne   tipc: add ip/udp ...
631
632
  	struct udp_media_addr local = {0};
  	struct udp_port_cfg udp_conf = {0};
4fee6be81   Erik Hugne   tipc: sparse: fix...
633
  	struct udp_tunnel_sock_cfg tuncfg = {NULL};
ba5aa84a2   Richard Alpe   tipc: split UDP n...
634
  	struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
52dfae5c8   Jon Maloy   tipc: obtain node...
635
  	u8 node_id[NODE_ID_LEN] = {0,};
4ef1a7cb0   Xin Long   ipv6: some fixes ...
636
  	struct net_device *dev;
acad76a5f   Hoang Le   tipc: support bin...
637
  	int rmcast = 0;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
638
639
640
641
  
  	ub = kzalloc(sizeof(*ub), GFP_ATOMIC);
  	if (!ub)
  		return -ENOMEM;
ef20cd4dd   Richard Alpe   tipc: introduce U...
642
  	INIT_LIST_HEAD(&ub->rcast.list);
ba5aa84a2   Richard Alpe   tipc: split UDP n...
643
644
  	if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
  		goto err;
8cb081746   Johannes Berg   netlink: make val...
645
  	if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attrs[TIPC_NLA_BEARER_UDP_OPTS], tipc_nl_udp_policy, NULL))
ba5aa84a2   Richard Alpe   tipc: split UDP n...
646
647
648
649
  		goto err;
  
  	if (!opts[TIPC_NLA_UDP_LOCAL] || !opts[TIPC_NLA_UDP_REMOTE]) {
  		pr_err("Invalid UDP bearer configuration");
c20cb8119   Wei Yongjun   tipc: fix possibl...
650
651
  		err = -EINVAL;
  		goto err;
ba5aa84a2   Richard Alpe   tipc: split UDP n...
652
653
654
655
656
657
  	}
  
  	err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_LOCAL], &local,
  				  &ub->ifindex);
  	if (err)
  		goto err;
ef20cd4dd   Richard Alpe   tipc: introduce U...
658
  	err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_REMOTE], &remote, NULL);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
659
660
  	if (err)
  		goto err;
fb83ed496   Cong Wang   tipc: compare rem...
661
662
663
664
  	if (remote.proto != local.proto) {
  		err = -EINVAL;
  		goto err;
  	}
acad76a5f   Hoang Le   tipc: support bin...
665
666
  	/* Checking remote ip address */
  	rmcast = tipc_udp_is_mcast_addr(&remote);
52dfae5c8   Jon Maloy   tipc: obtain node...
667
668
669
670
671
672
673
674
  	/* Autoconfigure own node identity if needed */
  	if (!tipc_own_id(net)) {
  		memcpy(node_id, local.ipv6.in6_u.u6_addr8, 16);
  		tipc_net_init(net, node_id, 0);
  	}
  	if (!tipc_own_id(net)) {
  		pr_warn("Failed to set node id, please configure manually
  ");
c76f2481b   Wei Yongjun   tipc: fix error h...
675
676
  		err = -EINVAL;
  		goto err;
52dfae5c8   Jon Maloy   tipc: obtain node...
677
  	}
d0f91938b   Erik Hugne   tipc: add ip/udp ...
678
  	b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP;
9999974a8   Jon Paul Maloy   tipc: add functio...
679
  	b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
680
681
682
  	rcu_assign_pointer(b->media_ptr, ub);
  	rcu_assign_pointer(ub->bearer, b);
  	tipc_udp_media_addr_set(&b->addr, &local);
4fee6be81   Erik Hugne   tipc: sparse: fix...
683
  	if (local.proto == htons(ETH_P_IP)) {
d0f91938b   Erik Hugne   tipc: add ip/udp ...
684
685
686
687
688
689
  		dev = __ip_dev_find(net, local.ipv4.s_addr, false);
  		if (!dev) {
  			err = -ENODEV;
  			goto err;
  		}
  		udp_conf.family = AF_INET;
acad76a5f   Hoang Le   tipc: support bin...
690
691
692
693
694
695
  
  		/* Switch to use ANY to receive packets from group */
  		if (rmcast)
  			udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
  		else
  			udp_conf.local_ip.s_addr = local.ipv4.s_addr;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
696
697
  		udp_conf.use_udp_checksums = false;
  		ub->ifindex = dev->ifindex;
3de81b758   Michal Kubeček   tipc: check minim...
698
699
700
701
702
  		if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
  				      sizeof(struct udphdr))) {
  			err = -EINVAL;
  			goto err;
  		}
a4dfa72d0   GhantaKrishnamurthy MohanKrishna   tipc: set default...
703
  		b->mtu = b->media->mtu;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
704
  #if IS_ENABLED(CONFIG_IPV6)
4fee6be81   Erik Hugne   tipc: sparse: fix...
705
  	} else if (local.proto == htons(ETH_P_IPV6)) {
4ef1a7cb0   Xin Long   ipv6: some fixes ...
706
707
  		dev = ub->ifindex ? __dev_get_by_index(net, ub->ifindex) : NULL;
  		dev = ipv6_dev_find(net, &local.ipv6, dev);
5a6f6f579   Xin Long   tipc: set ub->ifi...
708
709
710
711
  		if (!dev) {
  			err = -ENODEV;
  			goto err;
  		}
d0f91938b   Erik Hugne   tipc: add ip/udp ...
712
713
714
  		udp_conf.family = AF_INET6;
  		udp_conf.use_udp6_tx_checksums = true;
  		udp_conf.use_udp6_rx_checksums = true;
acad76a5f   Hoang Le   tipc: support bin...
715
716
717
718
  		if (rmcast)
  			udp_conf.local_ip6 = in6addr_any;
  		else
  			udp_conf.local_ip6 = local.ipv6;
5a6f6f579   Xin Long   tipc: set ub->ifi...
719
  		ub->ifindex = dev->ifindex;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
720
721
722
723
724
725
  		b->mtu = 1280;
  #endif
  	} else {
  		err = -EAFNOSUPPORT;
  		goto err;
  	}
bc3a334cc   Richard Alpe   tipc: rename udp_...
726
  	udp_conf.local_udp_port = local.port;
d0f91938b   Erik Hugne   tipc: add ip/udp ...
727
728
729
730
731
732
733
734
  	err = udp_sock_create(net, &udp_conf, &ub->ubsock);
  	if (err)
  		goto err;
  	tuncfg.sk_user_data = ub;
  	tuncfg.encap_type = 1;
  	tuncfg.encap_rcv = tipc_udp_recv;
  	tuncfg.encap_destroy = NULL;
  	setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
e9c1a7932   Xin Long   tipc: add dst_cac...
735
736
  	err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
  	if (err)
d2c3a4ba2   Xin Long   tipc: remove ub->...
737
  		goto free;
e9c1a7932   Xin Long   tipc: add dst_cac...
738

ef20cd4dd   Richard Alpe   tipc: introduce U...
739
740
741
742
743
  	/**
  	 * The bcast media address port is used for all peers and the ip
  	 * is used if it's a multicast address.
  	 */
  	memcpy(&b->bcast_addr.value, &remote, sizeof(remote));
acad76a5f   Hoang Le   tipc: support bin...
744
  	if (rmcast)
ef20cd4dd   Richard Alpe   tipc: introduce U...
745
746
747
748
  		err = enable_mcast(ub, &remote);
  	else
  		err = tipc_udp_rcast_add(b, &remote);
  	if (err)
d2c3a4ba2   Xin Long   tipc: remove ub->...
749
  		goto free;
1ca73e3fa   Richard Alpe   tipc: refactor mu...
750

d0f91938b   Erik Hugne   tipc: add ip/udp ...
751
  	return 0;
d2c3a4ba2   Xin Long   tipc: remove ub->...
752
753
  
  free:
e9c1a7932   Xin Long   tipc: add dst_cac...
754
  	dst_cache_destroy(&ub->rcast.dst_cache);
d2c3a4ba2   Xin Long   tipc: remove ub->...
755
756
  	udp_tunnel_sock_release(ub->ubsock);
  err:
d0f91938b   Erik Hugne   tipc: add ip/udp ...
757
758
759
760
761
762
763
764
  	kfree(ub);
  	return err;
  }
  
  /* cleanup_bearer - break the socket/bearer association */
  static void cleanup_bearer(struct work_struct *work)
  {
  	struct udp_bearer *ub = container_of(work, struct udp_bearer, work);
ef20cd4dd   Richard Alpe   tipc: introduce U...
765
766
767
  	struct udp_replicast *rcast, *tmp;
  
  	list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
e9c1a7932   Xin Long   tipc: add dst_cac...
768
  		dst_cache_destroy(&rcast->dst_cache);
ef20cd4dd   Richard Alpe   tipc: introduce U...
769
770
771
  		list_del_rcu(&rcast->list);
  		kfree_rcu(rcast, rcu);
  	}
d0f91938b   Erik Hugne   tipc: add ip/udp ...
772

e9c1a7932   Xin Long   tipc: add dst_cac...
773
  	dst_cache_destroy(&ub->rcast.dst_cache);
d2c3a4ba2   Xin Long   tipc: remove ub->...
774
  	udp_tunnel_sock_release(ub->ubsock);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
775
776
777
778
779
780
781
782
  	synchronize_net();
  	kfree(ub);
  }
  
  /* tipc_udp_disable - detach bearer from socket */
  static void tipc_udp_disable(struct tipc_bearer *b)
  {
  	struct udp_bearer *ub;
30a4616c1   Xin Long   tipc: use rcu der...
783
  	ub = rtnl_dereference(b->media_ptr);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
784
785
786
787
788
  	if (!ub) {
  		pr_err("UDP bearer instance not found
  ");
  		return;
  	}
d2c3a4ba2   Xin Long   tipc: remove ub->...
789
  	sock_set_flag(ub->ubsock->sk, SOCK_DEAD);
d0f91938b   Erik Hugne   tipc: add ip/udp ...
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
  	RCU_INIT_POINTER(ub->bearer, NULL);
  
  	/* sock_release need to be done outside of rtnl lock */
  	INIT_WORK(&ub->work, cleanup_bearer);
  	schedule_work(&ub->work);
  }
  
  struct tipc_media udp_media_info = {
  	.send_msg	= tipc_udp_send_msg,
  	.enable_media	= tipc_udp_enable,
  	.disable_media	= tipc_udp_disable,
  	.addr2str	= tipc_udp_addr2str,
  	.addr2msg	= tipc_udp_addr2msg,
  	.msg2addr	= tipc_udp_msg2addr,
  	.priority	= TIPC_DEF_LINK_PRI,
  	.tolerance	= TIPC_DEF_LINK_TOL,
16ad3f402   Jon Maloy   tipc: introduce v...
806
807
  	.min_win	= TIPC_DEF_LINK_WIN,
  	.max_win	= TIPC_DEF_LINK_WIN,
a4dfa72d0   GhantaKrishnamurthy MohanKrishna   tipc: set default...
808
  	.mtu		= TIPC_DEF_LINK_UDP_MTU,
d0f91938b   Erik Hugne   tipc: add ip/udp ...
809
810
811
812
  	.type_id	= TIPC_MEDIA_TYPE_UDP,
  	.hwaddr_len	= 0,
  	.name		= "udp"
  };