@@ -148,9 +148,11 @@ static void ops_free_list(const struct pernet_operations *ops,
148
148
}
149
149
}
150
150
151
+ static void rtnl_net_notifyid (struct net * net , struct net * peer , int cmd ,
152
+ int id );
151
153
static int alloc_netid (struct net * net , struct net * peer , int reqid )
152
154
{
153
- int min = 0 , max = 0 ;
155
+ int min = 0 , max = 0 , id ;
154
156
155
157
ASSERT_RTNL ();
156
158
@@ -159,7 +161,11 @@ static int alloc_netid(struct net *net, struct net *peer, int reqid)
159
161
max = reqid + 1 ;
160
162
}
161
163
162
- return idr_alloc (& net -> netns_ids , peer , min , max , GFP_KERNEL );
164
+ id = idr_alloc (& net -> netns_ids , peer , min , max , GFP_KERNEL );
165
+ if (id >= 0 )
166
+ rtnl_net_notifyid (net , peer , RTM_NEWNSID , id );
167
+
168
+ return id ;
163
169
}
164
170
165
171
/* This function is used by idr_for_each(). If net is equal to peer, the
@@ -359,8 +365,10 @@ static void cleanup_net(struct work_struct *work)
359
365
for_each_net (tmp ) {
360
366
int id = __peernet2id (tmp , net , false);
361
367
362
- if (id >= 0 )
368
+ if (id >= 0 ) {
369
+ rtnl_net_notifyid (tmp , net , RTM_DELNSID , id );
363
370
idr_remove (& tmp -> netns_ids , id );
371
+ }
364
372
}
365
373
idr_destroy (& net -> netns_ids );
366
374
@@ -531,7 +539,8 @@ static int rtnl_net_get_size(void)
531
539
}
532
540
533
541
static int rtnl_net_fill (struct sk_buff * skb , u32 portid , u32 seq , int flags ,
534
- int cmd , struct net * net , struct net * peer )
542
+ int cmd , struct net * net , struct net * peer ,
543
+ int nsid )
535
544
{
536
545
struct nlmsghdr * nlh ;
537
546
struct rtgenmsg * rth ;
@@ -546,9 +555,13 @@ static int rtnl_net_fill(struct sk_buff *skb, u32 portid, u32 seq, int flags,
546
555
rth = nlmsg_data (nlh );
547
556
rth -> rtgen_family = AF_UNSPEC ;
548
557
549
- id = __peernet2id (net , peer , false);
550
- if (id < 0 )
551
- id = NETNSA_NSID_NOT_ASSIGNED ;
558
+ if (nsid >= 0 ) {
559
+ id = nsid ;
560
+ } else {
561
+ id = __peernet2id (net , peer , false);
562
+ if (id < 0 )
563
+ id = NETNSA_NSID_NOT_ASSIGNED ;
564
+ }
552
565
if (nla_put_s32 (skb , NETNSA_NSID , id ))
553
566
goto nla_put_failure ;
554
567
@@ -589,7 +602,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh)
589
602
}
590
603
591
604
err = rtnl_net_fill (msg , NETLINK_CB (skb ).portid , nlh -> nlmsg_seq , 0 ,
592
- RTM_GETNSID , net , peer );
605
+ RTM_GETNSID , net , peer , -1 );
593
606
if (err < 0 )
594
607
goto err_out ;
595
608
@@ -603,6 +616,29 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh)
603
616
return err ;
604
617
}
605
618
619
+ static void rtnl_net_notifyid (struct net * net , struct net * peer , int cmd ,
620
+ int id )
621
+ {
622
+ struct sk_buff * msg ;
623
+ int err = - ENOMEM ;
624
+
625
+ msg = nlmsg_new (rtnl_net_get_size (), GFP_KERNEL );
626
+ if (!msg )
627
+ goto out ;
628
+
629
+ err = rtnl_net_fill (msg , 0 , 0 , 0 , cmd , net , peer , id );
630
+ if (err < 0 )
631
+ goto err_out ;
632
+
633
+ rtnl_notify (msg , net , 0 , RTNLGRP_NSID , NULL , 0 );
634
+ return ;
635
+
636
+ err_out :
637
+ nlmsg_free (msg );
638
+ out :
639
+ rtnl_set_sk_err (net , RTNLGRP_NSID , err );
640
+ }
641
+
606
642
static int __init net_ns_init (void )
607
643
{
608
644
struct net_generic * ng ;
0 commit comments