49
49
#include "core.h"
50
50
#include "bearer.h"
51
51
#include "netlink.h"
52
+ #include "msg.h"
52
53
53
54
/* IANA assigned UDP port */
54
55
#define UDP_PORT_DEFAULT 6118
@@ -70,6 +71,13 @@ struct udp_media_addr {
70
71
};
71
72
};
72
73
74
+ /* struct udp_replicast - container for UDP remote addresses */
75
+ struct udp_replicast {
76
+ struct udp_media_addr addr ;
77
+ struct rcu_head rcu ;
78
+ struct list_head list ;
79
+ };
80
+
73
81
/**
74
82
* struct udp_bearer - ip/udp bearer data structure
75
83
* @bearer: associated generic tipc bearer
@@ -82,6 +90,7 @@ struct udp_bearer {
82
90
struct socket * ubsock ;
83
91
u32 ifindex ;
84
92
struct work_struct work ;
93
+ struct udp_replicast rcast ;
85
94
};
86
95
87
96
static int tipc_udp_is_mcast_addr (struct udp_media_addr * addr )
@@ -203,29 +212,75 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
203
212
{
204
213
struct udp_media_addr * src = (struct udp_media_addr * )& b -> addr .value ;
205
214
struct udp_media_addr * dst = (struct udp_media_addr * )& addr -> value ;
215
+ struct udp_replicast * rcast ;
206
216
struct udp_bearer * ub ;
207
217
int err = 0 ;
208
218
209
219
if (skb_headroom (skb ) < UDP_MIN_HEADROOM ) {
210
220
err = pskb_expand_head (skb , UDP_MIN_HEADROOM , 0 , GFP_ATOMIC );
211
221
if (err )
212
- goto tx_error ;
222
+ goto out ;
213
223
}
214
224
215
225
skb_set_inner_protocol (skb , htons (ETH_P_TIPC ));
216
226
ub = rcu_dereference_rtnl (b -> media_ptr );
217
227
if (!ub ) {
218
228
err = - ENODEV ;
219
- goto tx_error ;
229
+ goto out ;
220
230
}
221
231
222
- return tipc_udp_xmit (net , skb , ub , src , dst );
232
+ if (!addr -> broadcast || list_empty (& ub -> rcast .list ))
233
+ return tipc_udp_xmit (net , skb , ub , src , dst );
223
234
224
- tx_error :
235
+ /* Replicast, send an skb to each configured IP address */
236
+ list_for_each_entry_rcu (rcast , & ub -> rcast .list , list ) {
237
+ struct sk_buff * _skb ;
238
+
239
+ _skb = pskb_copy (skb , GFP_ATOMIC );
240
+ if (!_skb ) {
241
+ err = - ENOMEM ;
242
+ goto out ;
243
+ }
244
+
245
+ err = tipc_udp_xmit (net , _skb , ub , src , & rcast -> addr );
246
+ if (err ) {
247
+ kfree_skb (_skb );
248
+ goto out ;
249
+ }
250
+ }
251
+ err = 0 ;
252
+ out :
225
253
kfree_skb (skb );
226
254
return err ;
227
255
}
228
256
257
+ static int tipc_udp_rcast_add (struct tipc_bearer * b ,
258
+ struct udp_media_addr * addr )
259
+ {
260
+ struct udp_replicast * rcast ;
261
+ struct udp_bearer * ub ;
262
+
263
+ ub = rcu_dereference_rtnl (b -> media_ptr );
264
+ if (!ub )
265
+ return - ENODEV ;
266
+
267
+ rcast = kmalloc (sizeof (* rcast ), GFP_ATOMIC );
268
+ if (!rcast )
269
+ return - ENOMEM ;
270
+
271
+ memcpy (& rcast -> addr , addr , sizeof (struct udp_media_addr ));
272
+
273
+ if (ntohs (addr -> proto ) == ETH_P_IP )
274
+ pr_info ("New replicast peer: %pI4\n" , & rcast -> addr .ipv4 );
275
+ #if IS_ENABLED (CONFIG_IPV6 )
276
+ else if (ntohs (addr -> proto ) == ETH_P_IPV6 )
277
+ pr_info ("New replicast peer: %pI6\n" , & rcast -> addr .ipv6 );
278
+ #endif
279
+
280
+ list_add_rcu (& rcast -> list , & ub -> rcast .list );
281
+ return 0 ;
282
+ }
283
+
229
284
/* tipc_udp_recv - read data from bearer socket */
230
285
static int tipc_udp_recv (struct sock * sk , struct sk_buff * skb )
231
286
{
@@ -320,6 +375,32 @@ static int tipc_parse_udp_addr(struct nlattr *nla, struct udp_media_addr *addr,
320
375
return - EADDRNOTAVAIL ;
321
376
}
322
377
378
+ int tipc_udp_nl_bearer_add (struct tipc_bearer * b , struct nlattr * attr )
379
+ {
380
+ int err ;
381
+ struct udp_media_addr addr = {0 };
382
+ struct nlattr * opts [TIPC_NLA_UDP_MAX + 1 ];
383
+ struct udp_media_addr * dst ;
384
+
385
+ if (nla_parse_nested (opts , TIPC_NLA_UDP_MAX , attr , tipc_nl_udp_policy ))
386
+ return - EINVAL ;
387
+
388
+ if (!opts [TIPC_NLA_UDP_REMOTE ])
389
+ return - EINVAL ;
390
+
391
+ err = tipc_parse_udp_addr (opts [TIPC_NLA_UDP_REMOTE ], & addr , NULL );
392
+ if (err )
393
+ return err ;
394
+
395
+ dst = (struct udp_media_addr * )& b -> bcast_addr .value ;
396
+ if (tipc_udp_is_mcast_addr (dst )) {
397
+ pr_err ("Can't add remote ip to TIPC UDP multicast bearer\n" );
398
+ return - EINVAL ;
399
+ }
400
+
401
+ return tipc_udp_rcast_add (b , & addr );
402
+ }
403
+
323
404
/**
324
405
* tipc_udp_enable - callback to create a new udp bearer instance
325
406
* @net: network namespace
@@ -334,7 +415,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
334
415
{
335
416
int err = - EINVAL ;
336
417
struct udp_bearer * ub ;
337
- struct udp_media_addr * remote ;
418
+ struct udp_media_addr remote = { 0 } ;
338
419
struct udp_media_addr local = {0 };
339
420
struct udp_port_cfg udp_conf = {0 };
340
421
struct udp_tunnel_sock_cfg tuncfg = {NULL };
@@ -344,6 +425,8 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
344
425
if (!ub )
345
426
return - ENOMEM ;
346
427
428
+ INIT_LIST_HEAD (& ub -> rcast .list );
429
+
347
430
if (!attrs [TIPC_NLA_BEARER_UDP_OPTS ])
348
431
goto err ;
349
432
@@ -362,9 +445,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
362
445
if (err )
363
446
goto err ;
364
447
365
- remote = (struct udp_media_addr * )& b -> bcast_addr .value ;
366
- memset (remote , 0 , sizeof (struct udp_media_addr ));
367
- err = tipc_parse_udp_addr (opts [TIPC_NLA_UDP_REMOTE ], remote , NULL );
448
+ err = tipc_parse_udp_addr (opts [TIPC_NLA_UDP_REMOTE ], & remote , NULL );
368
449
if (err )
369
450
goto err ;
370
451
@@ -409,10 +490,17 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
409
490
tuncfg .encap_destroy = NULL ;
410
491
setup_udp_tunnel_sock (net , ub -> ubsock , & tuncfg );
411
492
412
- if (tipc_udp_is_mcast_addr (remote )) {
413
- if (enable_mcast (ub , remote ))
414
- goto err ;
415
- }
493
+ /**
494
+ * The bcast media address port is used for all peers and the ip
495
+ * is used if it's a multicast address.
496
+ */
497
+ memcpy (& b -> bcast_addr .value , & remote , sizeof (remote ));
498
+ if (tipc_udp_is_mcast_addr (& remote ))
499
+ err = enable_mcast (ub , & remote );
500
+ else
501
+ err = tipc_udp_rcast_add (b , & remote );
502
+ if (err )
503
+ goto err ;
416
504
417
505
return 0 ;
418
506
err :
@@ -424,6 +512,12 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
424
512
static void cleanup_bearer (struct work_struct * work )
425
513
{
426
514
struct udp_bearer * ub = container_of (work , struct udp_bearer , work );
515
+ struct udp_replicast * rcast , * tmp ;
516
+
517
+ list_for_each_entry_safe (rcast , tmp , & ub -> rcast .list , list ) {
518
+ list_del_rcu (& rcast -> list );
519
+ kfree_rcu (rcast , rcu );
520
+ }
427
521
428
522
if (ub -> ubsock )
429
523
udp_tunnel_sock_release (ub -> ubsock );
0 commit comments