leaving function in locked state

File: net/ipv4/.tmp_igmp.o.preproc
Full description: {AutomatonChecker of /usr/share/stanse/checkers/AutomatonChecker/kernel_locking_irq.xml} in function 'igmp_mcf_seq_next' leaving function in locked state [traces: 1]
Importance: 1
Checker: AutomatonChecker of /usr/share/stanse/checkers/AutomatonChecker/kernel_locking_irq.xml
Trace:
line 2385: <context>When called from here.
line 2324: The lock is locked here.
line 2325: not affected ==> the lock is still locked.
line 2326: not affected ==> the lock is still locked.
line 2326: not affected ==> the lock is still locked.
line 2327: not affected ==> the lock is still locked.
line 2328: not affected ==> the lock is still locked.
line 2329: not affected ==> the lock is still locked.
line 2334: not affected ==> the lock is still locked.
line 2335: not affected ==> the lock is still locked.
line 2385: not affected ==> the lock is still locked.
line 2388: not affected ==> the lock is still locked.
line 2389: not affected ==> the lock is still locked.
line 2390: Leaving function in locked state.[& . * im_1 lock]
This one is:
False positive index (the lower the better): 0
File contents (this file is distributed under the terms specified in the original file):
    1|static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
    2|static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
    3|static void igmpv3_clear_delrec(struct in_device *in_dev);
    4|static int sf_setstate(struct ip_mc_list *pmc);
    5|static void sf_markstate(struct ip_mc_list *pmc);
    6|
    7|static void ip_mc_clear_src(struct ip_mc_list *pmc);
    8|static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
    9|    int sfcount, __be32 *psfsrc, int delta);
   10|
   11|
   12|static void ip_mc_list_reclaim(struct rcu_head *head)
   13|{
   14| kfree(({ const typeof( ((struct ip_mc_list *)0)->rcu ) *__mptr = (head); (struct ip_mc_list *)( (char *)__mptr - 1 );}));
   15|}
   16|
   17|static void ip_ma_put(struct ip_mc_list *im)
   18|{
   19| if (atomic_dec_and_test(&im->refcnt)) {
   20|  in_dev_put(im->interface);
   21|  call_rcu_sched(&im->rcu, ip_mc_list_reclaim);
   22| }
   23|}
   24|static void igmp_stop_timer(struct ip_mc_list *im)
   25|{
   26| __st_spin_lock_bh_st__(&im->lock);
   27| if (del_timer(&im->timer))
   28|  atomic_dec(&im->refcnt);
   29| im->tm_running = 0;
   30| im->reporter = 0;
   31| im->unsolicit_count = 0;
   32| __st_spin_unlock_bh_st__(&im->lock);
   33|}
   34|
   35|
   36|static void igmp_start_timer(struct ip_mc_list *im, int max_delay)
   37|{
   38| int tv = random32() % max_delay;
   39|
   40| im->tm_running = 1;
   41| if (!mod_timer(&im->timer, jiffies+tv+2))
   42|  atomic_inc(&im->refcnt);
   43|}
   44|
   45|static void igmp_gq_start_timer(struct in_device *in_dev)
   46|{
   47| int tv = random32() % in_dev->mr_maxdelay;
   48|
   49| in_dev->mr_gq_running = 1;
   50| if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2))
   51|  atomic_inc(&(in_dev)->refcnt);
   52|}
   53|
   54|static void igmp_ifc_start_timer(struct in_device *in_dev, int delay)
   55|{
   56| int tv = random32() % delay;
   57|
   58| if (!mod_timer(&in_dev->mr_ifc_timer, jiffies+tv+2))
   59|  atomic_inc(&(in_dev)->refcnt);
   60|}
   61|
   62|static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
   63|{
   64| __st_spin_lock_bh_st__(&im->lock);
   65| im->unsolicit_count = 0;
   66| if (del_timer(&im->timer)) {
   67|  if ((long)(im->timer.expires-jiffies) < max_delay) {
   68|   add_timer(&im->timer);
   69|   im->tm_running = 1;
   70|   __st_spin_unlock_bh_st__(&im->lock);
   71|   return;
   72|  }
   73|  atomic_dec(&im->refcnt);
   74| }
   75| igmp_start_timer(im, max_delay);
   76| __st_spin_unlock_bh_st__(&im->lock);
   77|}
   78|static int is_in(struct ip_mc_list *pmc, struct ip_sf_list *psf, int type,
   79| int gdeleted, int sdeleted)
   80|{
   81| switch (type) {
   82| case 1:
   83| case 2:
   84|  if (gdeleted || sdeleted)
   85|   return 0;
   86|  if (!(pmc->gsquery && !psf->sf_gsresp)) {
   87|   if (pmc->sfmode == 1)
   88|    return 1;
   89|
   90|
   91|
   92|   if (psf->sf_count[1])
   93|    return type == 1;
   94|   return pmc->sfcount[0] ==
   95|    psf->sf_count[0];
   96|  }
   97|  return 0;
   98| case 3:
   99|  if (gdeleted || sdeleted)
  100|   return 0;
  101|  return psf->sf_count[1] != 0;
  102| case 4:
  103|  if (gdeleted || sdeleted)
  104|   return 0;
  105|  if (pmc->sfcount[0] == 0 ||
  106|      psf->sf_count[1])
  107|   return 0;
  108|  return pmc->sfcount[0] ==
  109|   psf->sf_count[0];
  110| case 5:
  111|  if (gdeleted || !psf->sf_crcount)
  112|   return 0;
  113|  return (pmc->sfmode == 1) ^ sdeleted;
  114| case 6:
  115|  if (pmc->sfmode == 1)
  116|   return gdeleted || (psf->sf_crcount && sdeleted);
  117|  return psf->sf_crcount && !gdeleted && !sdeleted;
  118| }
  119| return 0;
  120|}
  121|
  122|static int
  123|igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
  124|{
  125| struct ip_sf_list *psf;
  126| int scount = 0;
  127|
  128| for (psf=pmc->sources; psf; psf=psf->sf_next) {
  129|  if (!is_in(pmc, psf, type, gdeleted, sdeleted))
  130|   continue;
  131|  scount++;
  132| }
  133| return scount;
  134|}
  135|
  136|
  137|
  138|static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
  139|{
  140| struct sk_buff *skb;
  141| struct rtable *rt;
  142| struct iphdr *pip;
  143| struct igmpv3_report *pig;
  144| struct net *net = dev_net(dev);
  145|
  146| while (1) {
  147|  skb = alloc_skb(size + ((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(16 - 1)) + 16),
  148|    ((( gfp_t)0x20u)) | (( gfp_t)0x200u));
  149|  if (skb)
  150|   break;
  151|  size >>= 1;
  152|  if (size < 256)
  153|   return ((void *)0);
  154| }
  155| (*(unsigned int *)((skb)->cb)) = size;
  156|
  157| {
  158|  struct flowi fl = { .oif = dev->ifindex,
  159|        .nl_u.ip4_u.daddr = (( __be32)(__builtin_constant_p((__u32)((0xE0000016L))) ? ((__u32)( (((__u32)((0xE0000016L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000016L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000016L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000016L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000016L)))),
  160|        .proto = IPPROTO_IGMP };
  161|  if (ip_route_output_key(net, &rt, &fl)) {
  162|   kfree_skb(skb);
  163|   return ((void *)0);
  164|  }
  165| }
  166| if (rt->rt_src == 0) {
  167|  kfree_skb(skb);
  168|  ip_rt_put(rt);
  169|  return ((void *)0);
  170| }
  171|
  172| skb_dst_set(skb, &rt->dst);
  173| skb->dev = dev;
  174|
  175| skb_reserve(skb, ((((dev)->hard_header_len+(dev)->needed_headroom)&~(16 - 1)) + 16));
  176|
  177| skb_reset_network_header(skb);
  178| pip = ip_hdr(skb);
  179| skb_put(skb, sizeof(struct iphdr) + 4);
  180|
  181| pip->version = 4;
  182| pip->ihl = (sizeof(struct iphdr)+4)>>2;
  183| pip->tos = 0xc0;
  184| pip->frag_off = (( __be16)(__builtin_constant_p((__u16)((0x4000))) ? ((__u16)( (((__u16)((0x4000)) & (__u16)0x00ffU) << 8) | (((__u16)((0x4000)) & (__u16)0xff00U) >> 8))) : __fswab16((0x4000))));
  185| pip->ttl = 1;
  186| pip->daddr = rt->rt_dst;
  187| pip->saddr = rt->rt_src;
  188| pip->protocol = IPPROTO_IGMP;
  189| pip->tot_len = 0;
  190| ip_select_ident(pip, &rt->dst, ((void *)0));
  191| ((u8*)&pip[1])[0] = (20|0x00|0x80);
  192| ((u8*)&pip[1])[1] = 4;
  193| ((u8*)&pip[1])[2] = 0;
  194| ((u8*)&pip[1])[3] = 0;
  195|
  196| skb->transport_header = skb->network_header + sizeof(struct iphdr) + 4;
  197| skb_put(skb, sizeof(*pig));
  198| pig = igmpv3_report_hdr(skb);
  199| pig->type = 0x22;
  200| pig->resv1 = 0;
  201| pig->csum = 0;
  202| pig->resv2 = 0;
  203| pig->ngrec = 0;
  204| return skb;
  205|}
  206|
  207|static int igmpv3_sendpack(struct sk_buff *skb)
  208|{
  209| struct igmphdr *pig = igmp_hdr(skb);
  210| const int igmplen = skb->tail - skb->transport_header;
  211|
  212| pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen);
  213|
  214| return ip_local_out(skb);
  215|}
  216|
  217|static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
  218|{
  219| return sizeof(struct igmpv3_grec) + 4*igmp_scount(pmc, type, gdel, sdel);
  220|}
  221|
  222|static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
  223| int type, struct igmpv3_grec **ppgr)
  224|{
  225| struct net_device *dev = pmc->interface->dev;
  226| struct igmpv3_report *pih;
  227| struct igmpv3_grec *pgr;
  228|
  229| if (!skb)
  230|  skb = igmpv3_newpack(dev, dev->mtu);
  231| if (!skb)
  232|  return ((void *)0);
  233| pgr = (struct igmpv3_grec *)skb_put(skb, sizeof(struct igmpv3_grec));
  234| pgr->grec_type = type;
  235| pgr->grec_auxwords = 0;
  236| pgr->grec_nsrcs = 0;
  237| pgr->grec_mca = pmc->multiaddr;
  238| pih = igmpv3_report_hdr(skb);
  239| pih->ngrec = (( __be16)(__builtin_constant_p((__u16)(((__builtin_constant_p((__u16)(( __u16)(__be16)(pih->ngrec))) ? ((__u16)( (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(pih->ngrec)))+1))) ? ((__u16)( (((__u16)(((__builtin_constant_p((__u16)(( __u16)(__be16)(pih->ngrec))) ? ((__u16)( (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(pih->ngrec)))+1)) & (__u16)0x00ffU) << 8) | (((__u16)(((__builtin_constant_p((__u16)(( __u16)(__be16)(pih->ngrec))) ? ((__u16)( (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(pih->ngrec)))+1)) & (__u16)0xff00U) >> 8))) : __fswab16(((__builtin_constant_p((__u16)(( __u16)(__be16)(pih->ngrec))) ? ((__u16)( (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(pih->ngrec)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(pih->ngrec)))+1))));
  240| *ppgr = pgr;
  241| return skb;
  242|}
  243|
  244|
  245|
  246|
  247|static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
  248| int type, int gdeleted, int sdeleted)
  249|{
  250| struct net_device *dev = pmc->interface->dev;
  251| struct igmpv3_report *pih;
  252| struct igmpv3_grec *pgr = ((void *)0);
  253| struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list;
  254| int scount, stotal, first, isquery, truncate;
  255|
  256| if (pmc->multiaddr == (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))))
  257|  return skb;
  258|
  259| isquery = type == 1 ||
  260|    type == 2;
  261| truncate = type == 2 ||
  262|      type == 4;
  263|
  264| stotal = scount = 0;
  265|
  266| psf_list = sdeleted ? &pmc->tomb : &pmc->sources;
  267|
  268| if (!*psf_list)
  269|  goto empty_source;
  270|
  271| pih = skb ? igmpv3_report_hdr(skb) : ((void *)0);
  272|
  273|
  274| if (truncate) {
  275|  if (pih && pih->ngrec &&
  276|      ((skb) ? ((skb)->dev ? (*(unsigned int *)((skb)->cb)) - (skb)->len : skb_tailroom(skb)) : 0) < grec_size(pmc, type, gdeleted, sdeleted)) {
  277|   if (skb)
  278|    igmpv3_sendpack(skb);
  279|   skb = igmpv3_newpack(dev, dev->mtu);
  280|  }
  281| }
  282| first = 1;
  283| psf_prev = ((void *)0);
  284| for (psf=*psf_list; psf; psf=psf_next) {
  285|  __be32 *psrc;
  286|
  287|  psf_next = psf->sf_next;
  288|
  289|  if (!is_in(pmc, psf, type, gdeleted, sdeleted)) {
  290|   psf_prev = psf;
  291|   continue;
  292|  }
  293|
  294|
  295|  if (isquery)
  296|   psf->sf_gsresp = 0;
  297|
  298|  if (((skb) ? ((skb)->dev ? (*(unsigned int *)((skb)->cb)) - (skb)->len : skb_tailroom(skb)) : 0) < sizeof(__be32) +
  299|      first*sizeof(struct igmpv3_grec)) {
  300|   if (truncate && !first)
  301|    break;
  302|   if (pgr)
  303|    pgr->grec_nsrcs = (( __be16)(__builtin_constant_p((__u16)((scount))) ? ((__u16)( (((__u16)((scount)) & (__u16)0x00ffU) << 8) | (((__u16)((scount)) & (__u16)0xff00U) >> 8))) : __fswab16((scount))));
  304|   if (skb)
  305|    igmpv3_sendpack(skb);
  306|   skb = igmpv3_newpack(dev, dev->mtu);
  307|   first = 1;
  308|   scount = 0;
  309|  }
  310|  if (first) {
  311|   skb = add_grhead(skb, pmc, type, &pgr);
  312|   first = 0;
  313|  }
  314|  if (!skb)
  315|   return ((void *)0);
  316|  psrc = (__be32 *)skb_put(skb, sizeof(__be32));
  317|  *psrc = psf->sf_inaddr;
  318|  scount++; stotal++;
  319|  if ((type == 5 ||
  320|       type == 6) && psf->sf_crcount) {
  321|   psf->sf_crcount--;
  322|   if ((sdeleted || gdeleted) && psf->sf_crcount == 0) {
  323|    if (psf_prev)
  324|     psf_prev->sf_next = psf->sf_next;
  325|    else
  326|     *psf_list = psf->sf_next;
  327|    kfree(psf);
  328|    continue;
  329|   }
  330|  }
  331|  psf_prev = psf;
  332| }
  333|
  334|empty_source:
  335| if (!stotal) {
  336|  if (type == 5 ||
  337|      type == 6)
  338|   return skb;
  339|  if (pmc->crcount || isquery) {
  340|
  341|   if (skb && ((skb) ? ((skb)->dev ? (*(unsigned int *)((skb)->cb)) - (skb)->len : skb_tailroom(skb)) : 0)  342|    igmpv3_sendpack(skb);
  343|    skb = ((void *)0);
  344|   }
  345|   skb = add_grhead(skb, pmc, type, &pgr);
  346|  }
  347| }
  348| if (pgr)
  349|  pgr->grec_nsrcs = (( __be16)(__builtin_constant_p((__u16)((scount))) ? ((__u16)( (((__u16)((scount)) & (__u16)0x00ffU) << 8) | (((__u16)((scount)) & (__u16)0xff00U) >> 8))) : __fswab16((scount))));
  350|
  351| if (isquery)
  352|  pmc->gsquery = 0;
  353| return skb;
  354|}
  355|
  356|static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
  357|{
  358| struct sk_buff *skb = ((void *)0);
  359| int type;
  360|
  361| if (!pmc) {
  362|  __st_rcu_read_lock_st__();
  363|  for (pmc = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 530); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); pmc != ((void *)0); pmc = ({ typeof(*(pmc->next_rcu)) *_________p1 = (typeof(*(pmc->next_rcu))* )(*(volatile typeof((pmc->next_rcu)) *)&((pmc->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 530); } } while (0); ; do { } while (0); ((typeof(*(pmc->next_rcu)) *)(_________p1)); })) {
  364|   if (pmc->multiaddr == (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))))
  365|    continue;
  366|   __st_spin_lock_bh_st__(&pmc->lock);
  367|   if (pmc->sfcount[0])
  368|    type = 2;
  369|   else
  370|    type = 1;
  371|   skb = add_grec(skb, pmc, type, 0, 0);
  372|   __st_spin_unlock_bh_st__(&pmc->lock);
  373|  }
  374|  __st_rcu_read_unlock_st__();
  375| } else {
  376|  __st_spin_lock_bh_st__(&pmc->lock);
  377|  if (pmc->sfcount[0])
  378|   type = 2;
  379|  else
  380|   type = 1;
  381|  skb = add_grec(skb, pmc, type, 0, 0);
  382|  __st_spin_unlock_bh_st__(&pmc->lock);
  383| }
  384| if (!skb)
  385|  return 0;
  386| return igmpv3_sendpack(skb);
  387|}
  388|
  389|
  390|
  391|
  392|static void igmpv3_clear_zeros(struct ip_sf_list **ppsf)
  393|{
  394| struct ip_sf_list *psf_prev, *psf_next, *psf;
  395|
  396| psf_prev = ((void *)0);
  397| for (psf=*ppsf; psf; psf = psf_next) {
  398|  psf_next = psf->sf_next;
  399|  if (psf->sf_crcount == 0) {
  400|   if (psf_prev)
  401|    psf_prev->sf_next = psf->sf_next;
  402|   else
  403|    *ppsf = psf->sf_next;
  404|   kfree(psf);
  405|  } else
  406|   psf_prev = psf;
  407| }
  408|}
  409|
  410|static void igmpv3_send_cr(struct in_device *in_dev)
  411|{
  412| struct ip_mc_list *pmc, *pmc_prev, *pmc_next;
  413| struct sk_buff *skb = ((void *)0);
  414| int type, dtype;
  415|
  416| __st_rcu_read_lock_st__();
  417| __st_spin_lock_bh_st__(&in_dev->mc_tomb_lock);
  418|
  419|
  420| pmc_prev = ((void *)0);
  421| for (pmc=in_dev->mc_tomb; pmc; pmc=pmc_next) {
  422|  pmc_next = pmc->next;
  423|  if (pmc->sfmode == 1) {
  424|   type = 6;
  425|   dtype = 6;
  426|   skb = add_grec(skb, pmc, type, 1, 0);
  427|   skb = add_grec(skb, pmc, dtype, 1, 1);
  428|  }
  429|  if (pmc->crcount) {
  430|   if (pmc->sfmode == 0) {
  431|    type = 3;
  432|    skb = add_grec(skb, pmc, type, 1, 0);
  433|   }
  434|   pmc->crcount--;
  435|   if (pmc->crcount == 0) {
  436|    igmpv3_clear_zeros(&pmc->tomb);
  437|    igmpv3_clear_zeros(&pmc->sources);
  438|   }
  439|  }
  440|  if (pmc->crcount == 0 && !pmc->tomb && !pmc->sources) {
  441|   if (pmc_prev)
  442|    pmc_prev->next = pmc_next;
  443|   else
  444|    in_dev->mc_tomb = pmc_next;
  445|   in_dev_put(pmc->interface);
  446|   kfree(pmc);
  447|  } else
  448|   pmc_prev = pmc;
  449| }
  450| __st_spin_unlock_bh_st__(&in_dev->mc_tomb_lock);
  451|
  452|
  453| for (pmc = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 620); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); pmc != ((void *)0); pmc = ({ typeof(*(pmc->next_rcu)) *_________p1 = (typeof(*(pmc->next_rcu))* )(*(volatile typeof((pmc->next_rcu)) *)&((pmc->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 620); } } while (0); ; do { } while (0); ((typeof(*(pmc->next_rcu)) *)(_________p1)); })) {
  454|  __st_spin_lock_bh_st__(&pmc->lock);
  455|  if (pmc->sfcount[0]) {
  456|   type = 6;
  457|   dtype = 5;
  458|  } else {
  459|   type = 5;
  460|   dtype = 6;
  461|  }
  462|  skb = add_grec(skb, pmc, type, 0, 0);
  463|  skb = add_grec(skb, pmc, dtype, 0, 1);
  464|
  465|
  466|  if (pmc->crcount) {
  467|   if (pmc->sfmode == 0)
  468|    type = 4;
  469|   else
  470|    type = 3;
  471|   skb = add_grec(skb, pmc, type, 0, 0);
  472|   pmc->crcount--;
  473|  }
  474|  __st_spin_unlock_bh_st__(&pmc->lock);
  475| }
  476| __st_rcu_read_unlock_st__();
  477|
  478| if (!skb)
  479|  return;
  480| (void) igmpv3_sendpack(skb);
  481|}
  482|
  483|static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
  484| int type)
  485|{
  486| struct sk_buff *skb;
  487| struct iphdr *iph;
  488| struct igmphdr *ih;
  489| struct rtable *rt;
  490| struct net_device *dev = in_dev->dev;
  491| struct net *net = dev_net(dev);
  492| __be32 group = pmc ? pmc->multiaddr : 0;
  493| __be32 dst;
  494|
  495| if (type == 0x22)
  496|  return igmpv3_send_report(in_dev, pmc);
  497| else if (type == 0x17)
  498|  dst = (( __be32)(__builtin_constant_p((__u32)((0xE0000002L))) ? ((__u32)( (((__u32)((0xE0000002L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000002L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000002L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000002L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000002L))));
  499| else
  500|  dst = group;
  501|
  502| {
  503|  struct flowi fl = { .oif = dev->ifindex,
  504|        .nl_u.ip4_u.daddr = dst,
  505|        .proto = IPPROTO_IGMP };
  506|  if (ip_route_output_key(net, &rt, &fl))
  507|   return -1;
  508| }
  509| if (rt->rt_src == 0) {
  510|  ip_rt_put(rt);
  511|  return -1;
  512| }
  513|
  514| skb = alloc_skb((sizeof(struct igmphdr)+sizeof(struct iphdr)+4)+((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(16 - 1)) + 16), ((( gfp_t)0x20u)));
  515| if (skb == ((void *)0)) {
  516|  ip_rt_put(rt);
  517|  return -1;
  518| }
  519|
  520| skb_dst_set(skb, &rt->dst);
  521|
  522| skb_reserve(skb, ((((dev)->hard_header_len+(dev)->needed_headroom)&~(16 - 1)) + 16));
  523|
  524| skb_reset_network_header(skb);
  525| iph = ip_hdr(skb);
  526| skb_put(skb, sizeof(struct iphdr) + 4);
  527|
  528| iph->version = 4;
  529| iph->ihl = (sizeof(struct iphdr)+4)>>2;
  530| iph->tos = 0xc0;
  531| iph->frag_off = (( __be16)(__builtin_constant_p((__u16)((0x4000))) ? ((__u16)( (((__u16)((0x4000)) & (__u16)0x00ffU) << 8) | (((__u16)((0x4000)) & (__u16)0xff00U) >> 8))) : __fswab16((0x4000))));
  532| iph->ttl = 1;
  533| iph->daddr = dst;
  534| iph->saddr = rt->rt_src;
  535| iph->protocol = IPPROTO_IGMP;
  536| ip_select_ident(iph, &rt->dst, ((void *)0));
  537| ((u8*)&iph[1])[0] = (20|0x00|0x80);
  538| ((u8*)&iph[1])[1] = 4;
  539| ((u8*)&iph[1])[2] = 0;
  540| ((u8*)&iph[1])[3] = 0;
  541|
  542| ih = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
  543| ih->type = type;
  544| ih->code = 0;
  545| ih->csum = 0;
  546| ih->group = group;
  547| ih->csum = ip_compute_csum((void *)ih, sizeof(struct igmphdr));
  548|
  549| return ip_local_out(skb);
  550|}
  551|
  552|static void igmp_gq_timer_expire(unsigned long data)
  553|{
  554| struct in_device *in_dev = (struct in_device *)data;
  555|
  556| in_dev->mr_gq_running = 0;
  557| igmpv3_send_report(in_dev, ((void *)0));
  558| atomic_dec(&(in_dev)->refcnt);
  559|}
  560|
  561|static void igmp_ifc_timer_expire(unsigned long data)
  562|{
  563| struct in_device *in_dev = (struct in_device *)data;
  564|
  565| igmpv3_send_cr(in_dev);
  566| if (in_dev->mr_ifc_count) {
  567|  in_dev->mr_ifc_count--;
  568|  igmp_ifc_start_timer(in_dev, (10*250));
  569| }
  570| atomic_dec(&(in_dev)->refcnt);
  571|}
  572|
  573|static void igmp_ifc_event(struct in_device *in_dev)
  574|{
  575| if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v1_seen) < 0)))) || ((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v2_seen) < 0)))))
  576|  return;
  577| in_dev->mr_ifc_count = in_dev->mr_qrv ? in_dev->mr_qrv :
  578|  2;
  579| igmp_ifc_start_timer(in_dev, 1);
  580|}
  581|
  582|
  583|static void igmp_timer_expire(unsigned long data)
  584|{
  585| struct ip_mc_list *im=(struct ip_mc_list *)data;
  586| struct in_device *in_dev = im->interface;
  587|
  588| __st_spin_lock_st__(&im->lock);
  589| im->tm_running = 0;
  590|
  591| if (im->unsolicit_count) {
  592|  im->unsolicit_count--;
  593|  igmp_start_timer(im, (10*250));
  594| }
  595| im->reporter = 1;
  596| __st_spin_unlock_st__(&im->lock);
  597|
  598| if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v1_seen) < 0)))))
  599|  igmp_send_report(in_dev, im, 0x12);
  600| else if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v2_seen) < 0)))))
  601|  igmp_send_report(in_dev, im, 0x16);
  602| else
  603|  igmp_send_report(in_dev, im, 0x22);
  604|
  605| ip_ma_put(im);
  606|}
  607|
  608|
  609|static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
  610|{
  611| struct ip_sf_list *psf;
  612| int i, scount;
  613|
  614| scount = 0;
  615| for (psf=pmc->sources; psf; psf=psf->sf_next) {
  616|  if (scount == nsrcs)
  617|   break;
  618|  for (i=0; i  619|
  620|   if (pmc->sfcount[1] ||
  621|       pmc->sfcount[0] !=
  622|       psf->sf_count[0])
  623|    continue;
  624|   if (srcs[i] == psf->sf_inaddr) {
  625|    scount++;
  626|    break;
  627|   }
  628|  }
  629| }
  630| pmc->gsquery = 0;
  631| if (scount == nsrcs)
  632|  return 0;
  633| return 1;
  634|}
  635|
  636|static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
  637|{
  638| struct ip_sf_list *psf;
  639| int i, scount;
  640|
  641| if (pmc->sfmode == 0)
  642|  return igmp_xmarksources(pmc, nsrcs, srcs);
  643|
  644|
  645| scount = 0;
  646| for (psf=pmc->sources; psf; psf=psf->sf_next) {
  647|  if (scount == nsrcs)
  648|   break;
  649|  for (i=0; i  650|   if (srcs[i] == psf->sf_inaddr) {
  651|    psf->sf_gsresp = 1;
  652|    scount++;
  653|    break;
  654|   }
  655| }
  656| if (!scount) {
  657|  pmc->gsquery = 0;
  658|  return 0;
  659| }
  660| pmc->gsquery = 1;
  661| return 1;
  662|}
  663|
  664|static void igmp_heard_report(struct in_device *in_dev, __be32 group)
  665|{
  666| struct ip_mc_list *im;
  667|
  668|
  669|
  670| if (group == (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))))
  671|  return;
  672|
  673| __st_rcu_read_lock_st__();
  674| for (im = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 841); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); im != ((void *)0); im = ({ typeof(*(im->next_rcu)) *_________p1 = (typeof(*(im->next_rcu))* )(*(volatile typeof((im->next_rcu)) *)&((im->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 841); } } while (0); ; do { } while (0); ((typeof(*(im->next_rcu)) *)(_________p1)); })) {
  675|  if (im->multiaddr == group) {
  676|   igmp_stop_timer(im);
  677|   break;
  678|  }
  679| }
  680| __st_rcu_read_unlock_st__();
  681|}
  682|
  683|static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
  684| int len)
  685|{
  686| struct igmphdr *ih = igmp_hdr(skb);
  687| struct igmpv3_query *ih3 = igmpv3_query_hdr(skb);
  688| struct ip_mc_list *im;
  689| __be32 group = ih->group;
  690| int max_delay;
  691| int mark = 0;
  692|
  693|
  694| if (len == 8) {
  695|  if (ih->code == 0) {
  696|
  697|
  698|   max_delay = (10*250);
  699|   in_dev->mr_v1_seen = jiffies +
  700|    (400*250);
  701|   group = 0;
  702|  } else {
  703|
  704|   max_delay = ih->code*(250/10);
  705|   in_dev->mr_v2_seen = jiffies +
  706|    (400*250);
  707|  }
  708|
  709|  in_dev->mr_ifc_count = 0;
  710|  if (del_timer(&in_dev->mr_ifc_timer))
  711|   atomic_dec(&(in_dev)->refcnt);
  712|
  713|  igmpv3_clear_delrec(in_dev);
  714| } else if (len < 12) {
  715|  return;
  716| } else if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v1_seen) < 0))))) {
  717|
  718|  max_delay = (10*250);
  719|  group = 0;
  720| } else if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v2_seen) < 0))))) {
  721|
  722|
  723|
  724|
  725|
  726|
  727|  max_delay = ((ih3->code) < (0x80) ? (ih3->code) : ((((4)>=32 ? (ih3->code) : ((1<<(4))-1) & (ih3->code)) | (1<<(4))) << (((3)>=32 ? ((ih3->code) >> (4)) : ((1<<(3))-1) & ((ih3->code) >> (4))) + (3))))*(250/10);
  728| } else {
  729|  if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
  730|   return;
  731|
  732|  ih3 = igmpv3_query_hdr(skb);
  733|  if (ih3->nsrcs) {
  734|   if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)
  735|        + (__builtin_constant_p((__u16)(( __u16)(__be16)(ih3->nsrcs))) ? ((__u16)( (((__u16)(( __u16)(__be16)(ih3->nsrcs)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(ih3->nsrcs)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(ih3->nsrcs)))*sizeof(__be32)))
  736|    return;
  737|   ih3 = igmpv3_query_hdr(skb);
  738|  }
  739|
  740|  max_delay = ((ih3->code) < (0x80) ? (ih3->code) : ((((4)>=32 ? (ih3->code) : ((1<<(4))-1) & (ih3->code)) | (1<<(4))) << (((3)>=32 ? ((ih3->code) >> (4)) : ((1<<(3))-1) & ((ih3->code) >> (4))) + (3))))*(250/10);
  741|  if (!max_delay)
  742|   max_delay = 1;
  743|  in_dev->mr_maxdelay = max_delay;
  744|  if (ih3->qrv)
  745|   in_dev->mr_qrv = ih3->qrv;
  746|  if (!group) {
  747|   if (ih3->nsrcs)
  748|    return;
  749|   igmp_gq_start_timer(in_dev);
  750|   return;
  751|  }
  752|
  753|  mark = ih3->nsrcs != 0;
  754| }
  755| __st_rcu_read_lock_st__();
  756| for (im = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 934); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); im != ((void *)0); im = ({ typeof(*(im->next_rcu)) *_________p1 = (typeof(*(im->next_rcu))* )(*(volatile typeof((im->next_rcu)) *)&((im->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 934); } } while (0); ; do { } while (0); ((typeof(*(im->next_rcu)) *)(_________p1)); })) {
  757|  int changed;
  758|
  759|  if (group && group != im->multiaddr)
  760|   continue;
  761|  if (im->multiaddr == (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))))
  762|   continue;
  763|  __st_spin_lock_bh_st__(&im->lock);
  764|  if (im->tm_running)
  765|   im->gsquery = im->gsquery && mark;
  766|  else
  767|   im->gsquery = mark;
  768|  changed = !im->gsquery ||
  769|   igmp_marksources(im, (__builtin_constant_p((__u16)(( __u16)(__be16)(ih3->nsrcs))) ? ((__u16)( (((__u16)(( __u16)(__be16)(ih3->nsrcs)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(ih3->nsrcs)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(ih3->nsrcs))), ih3->srcs);
  770|  __st_spin_unlock_bh_st__(&im->lock);
  771|  if (changed)
  772|   igmp_mod_timer(im, max_delay);
  773| }
  774| __st_rcu_read_unlock_st__();
  775|}
  776|
  777|
  778|int igmp_rcv(struct sk_buff *skb)
  779|{
  780|
  781| struct igmphdr *ih;
  782| struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
  783| int len = skb->len;
  784|
  785| if (in_dev == ((void *)0))
  786|  goto drop;
  787|
  788| if (!pskb_may_pull(skb, sizeof(struct igmphdr)))
  789|  goto drop;
  790|
  791| switch (skb->ip_summed) {
  792| case 2:
  793|  if (!csum_fold(skb->csum))
  794|   break;
  795|
  796| case 0:
  797|  skb->csum = 0;
  798|  if (__skb_checksum_complete(skb))
  799|   goto drop;
  800| }
  801|
  802| ih = igmp_hdr(skb);
  803| switch (ih->type) {
  804| case 0x11:
  805|  igmp_heard_query(in_dev, skb, len);
  806|  break;
  807| case 0x12:
  808| case 0x16:
  809|
  810|  if (rt_is_output_route(skb_rtable(skb)))
  811|   break;
  812|
  813|  if (skb->pkt_type == 2 ||
  814|      skb->pkt_type == 1)
  815|   igmp_heard_report(in_dev, ih->group);
  816|  break;
  817| case 0x14:
  818|
  819|  return pim_rcv_v1(skb);
  820|
  821| case 0x22:
  822| case 0x13:
  823| case 0x15:
  824| case 0x17:
  825| case 0x1f:
  826| case 0x1e:
  827|  break;
  828| default:
  829|  break;
  830| }
  831|
  832|drop:
  833| kfree_skb(skb);
  834| return 0;
  835|}
  836|static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr)
  837|{
  838| char buf[32];
  839| struct net_device *dev = in_dev->dev;
  840| if (arp_mc_map(addr, buf, dev, 0) == 0)
  841|  dev_mc_add(dev, buf);
  842|}
  843|
  844|
  845|
  846|
  847|
  848|static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr)
  849|{
  850| char buf[32];
  851| struct net_device *dev = in_dev->dev;
  852|
  853| if (arp_mc_map(addr, buf, dev, 0) == 0)
  854|  dev_mc_del(dev, buf);
  855|}
  856|
  857|
  858|
  859|
  860|
  861|static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
  862|{
  863| struct ip_mc_list *pmc;
  864|
  865|
  866|
  867|
  868|
  869|
  870|
  871| pmc = kzalloc(sizeof(*pmc), __st_GFP_KERNEL_st__);
  872| if (!pmc)
  873|  return;
  874| __st_spin_lock_bh_st__(&im->lock);
  875| pmc->interface = im->interface;
  876| atomic_inc(&(in_dev)->refcnt);
  877| pmc->multiaddr = im->multiaddr;
  878| pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
  879|  2;
  880| pmc->sfmode = im->sfmode;
  881| if (pmc->sfmode == 1) {
  882|  struct ip_sf_list *psf;
  883|
  884|  pmc->tomb = im->tomb;
  885|  pmc->sources = im->sources;
  886|  im->tomb = im->sources = ((void *)0);
  887|  for (psf=pmc->sources; psf; psf=psf->sf_next)
  888|   psf->sf_crcount = pmc->crcount;
  889| }
  890| __st_spin_unlock_bh_st__(&im->lock);
  891|
  892| __st_spin_lock_bh_st__(&in_dev->mc_tomb_lock);
  893| pmc->next = in_dev->mc_tomb;
  894| in_dev->mc_tomb = pmc;
  895| __st_spin_unlock_bh_st__(&in_dev->mc_tomb_lock);
  896|}
  897|
  898|static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr)
  899|{
  900| struct ip_mc_list *pmc, *pmc_prev;
  901| struct ip_sf_list *psf, *psf_next;
  902|
  903| __st_spin_lock_bh_st__(&in_dev->mc_tomb_lock);
  904| pmc_prev = ((void *)0);
  905| for (pmc=in_dev->mc_tomb; pmc; pmc=pmc->next) {
  906|  if (pmc->multiaddr == multiaddr)
  907|   break;
  908|  pmc_prev = pmc;
  909| }
  910| if (pmc) {
  911|  if (pmc_prev)
  912|   pmc_prev->next = pmc->next;
  913|  else
  914|   in_dev->mc_tomb = pmc->next;
  915| }
  916| __st_spin_unlock_bh_st__(&in_dev->mc_tomb_lock);
  917| if (pmc) {
  918|  for (psf=pmc->tomb; psf; psf=psf_next) {
  919|   psf_next = psf->sf_next;
  920|   kfree(psf);
  921|  }
  922|  in_dev_put(pmc->interface);
  923|  kfree(pmc);
  924| }
  925|}
  926|
  927|static void igmpv3_clear_delrec(struct in_device *in_dev)
  928|{
  929| struct ip_mc_list *pmc, *nextpmc;
  930|
  931| __st_spin_lock_bh_st__(&in_dev->mc_tomb_lock);
  932| pmc = in_dev->mc_tomb;
  933| in_dev->mc_tomb = ((void *)0);
  934| __st_spin_unlock_bh_st__(&in_dev->mc_tomb_lock);
  935|
  936| for (; pmc; pmc = nextpmc) {
  937|  nextpmc = pmc->next;
  938|  ip_mc_clear_src(pmc);
  939|  in_dev_put(pmc->interface);
  940|  kfree(pmc);
  941| }
  942|
  943| __st_rcu_read_lock_st__();
  944| for (pmc = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1138); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); pmc != ((void *)0); pmc = ({ typeof(*(pmc->next_rcu)) *_________p1 = (typeof(*(pmc->next_rcu))* )(*(volatile typeof((pmc->next_rcu)) *)&((pmc->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1138); } } while (0); ; do { } while (0); ((typeof(*(pmc->next_rcu)) *)(_________p1)); })) {
  945|  struct ip_sf_list *psf, *psf_next;
  946|
  947|  __st_spin_lock_bh_st__(&pmc->lock);
  948|  psf = pmc->tomb;
  949|  pmc->tomb = ((void *)0);
  950|  __st_spin_unlock_bh_st__(&pmc->lock);
  951|  for (; psf; psf=psf_next) {
  952|   psf_next = psf->sf_next;
  953|   kfree(psf);
  954|  }
  955| }
  956| __st_rcu_read_unlock_st__();
  957|}
  958|
  959|
  960|static void igmp_group_dropped(struct ip_mc_list *im)
  961|{
  962| struct in_device *in_dev = im->interface;
  963|
  964| int reporter;
  965|
  966|
  967| if (im->loaded) {
  968|  im->loaded = 0;
  969|  ip_mc_filter_del(in_dev, im->multiaddr);
  970| }
  971|
  972|
  973| if (im->multiaddr == (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))))
  974|  return;
  975|
  976| reporter = im->reporter;
  977| igmp_stop_timer(im);
  978|
  979| if (!in_dev->dead) {
  980|  if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v1_seen) < 0)))))
  981|   goto done;
  982|  if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v2_seen) < 0))))) {
  983|   if (reporter)
  984|    igmp_send_report(in_dev, im, 0x17);
  985|   goto done;
  986|  }
  987|
  988|  igmpv3_add_delrec(in_dev, im);
  989|
  990|  igmp_ifc_event(in_dev);
  991| }
  992|done:
  993|
  994| ip_mc_clear_src(im);
  995|}
  996|
  997|static void igmp_group_added(struct ip_mc_list *im)
  998|{
  999| struct in_device *in_dev = im->interface;
 1000|
 1001| if (im->loaded == 0) {
 1002|  im->loaded = 1;
 1003|  ip_mc_filter_add(in_dev, im->multiaddr);
 1004| }
 1005|
 1006|
 1007| if (im->multiaddr == (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))))
 1008|  return;
 1009|
 1010| if (in_dev->dead)
 1011|  return;
 1012| if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v1_seen) < 0)))) || ((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v2_seen) < 0))))) {
 1013|  __st_spin_lock_bh_st__(&im->lock);
 1014|  igmp_start_timer(im, (1));
 1015|  __st_spin_unlock_bh_st__(&im->lock);
 1016|  return;
 1017| }
 1018|
 1019|
 1020| im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
 1021|  2;
 1022| igmp_ifc_event(in_dev);
 1023|
 1024|}
 1025|void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
 1026|{
 1027| struct ip_mc_list *im;
 1028|
 1029| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1234); dump_stack(); } } while(0);
 1030|
 1031| for (im = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1236); } } while (0); ; ((typeof(*(in_dev->mc_list)) *)((in_dev->mc_list))); }); im != ((void *)0); im = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1236); } } while (0); ; ((typeof(*(im->next_rcu)) *)((im->next_rcu))); })) {
 1032|  if (im->multiaddr == addr) {
 1033|   im->users++;
 1034|   ip_mc_add_src(in_dev, &addr, 0, 0, ((void *)0), 0);
 1035|   goto out;
 1036|  }
 1037| }
 1038|
 1039| im = kzalloc(sizeof(*im), __st_GFP_KERNEL_st__);
 1040| if (!im)
 1041|  goto out;
 1042|
 1043| im->users = 1;
 1044| im->interface = in_dev;
 1045| atomic_inc(&(in_dev)->refcnt);
 1046| im->multiaddr = addr;
 1047|
 1048| im->sfmode = 0;
 1049| im->sfcount[0] = 1;
 1050| atomic_set(&im->refcnt, 1);
 1051| do { spinlock_check(&im->lock); do { static struct lock_class_key __key; __raw_spin_lock_init((&(&im->lock)->rlock), "&(&im->lock)->rlock", &__key); } while (0); } while (0);
 1052|
 1053| do { static struct lock_class_key __key; setup_timer_key((&im->timer), "&im->timer", &__key, (&igmp_timer_expire), ((unsigned long)im)); } while (0);
 1054| im->unsolicit_count = 2;
 1055|
 1056|
 1057| im->next_rcu = in_dev->mc_list;
 1058| in_dev->mc_count++;
 1059| __st_rcu_assign_pointer_st__(in_dev->mc_list, im);
 1060|
 1061|
 1062| igmpv3_del_delrec(in_dev, im->multiaddr);
 1063|
 1064| igmp_group_added(im);
 1065| if (!in_dev->dead)
 1066|  ip_rt_multicast_event(in_dev);
 1067|out:
 1068| return;
 1069|}
 1070|extern typeof(ip_mc_inc_group) ip_mc_inc_group; extern void *__crc_ip_mc_inc_group ; static const unsigned long __kcrctab_ip_mc_inc_group = (unsigned long) &__crc_ip_mc_inc_group; static const char __kstrtab_ip_mc_inc_group[] = "" "ip_mc_inc_group"; static const struct kernel_symbol __ksymtab_ip_mc_inc_group = { (unsigned long)&ip_mc_inc_group, __kstrtab_ip_mc_inc_group };
 1071|
 1072|
 1073|
 1074|
 1075|
 1076|void ip_mc_rejoin_groups(struct in_device *in_dev)
 1077|{
 1078|
 1079| struct ip_mc_list *im;
 1080| int type;
 1081|
 1082| for (im = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1287); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); im != ((void *)0); im = ({ typeof(*(im->next_rcu)) *_________p1 = (typeof(*(im->next_rcu))* )(*(volatile typeof((im->next_rcu)) *)&((im->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1287); } } while (0); ; do { } while (0); ((typeof(*(im->next_rcu)) *)(_________p1)); })) {
 1083|  if (im->multiaddr == (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))))
 1084|   continue;
 1085|
 1086|
 1087|
 1088|
 1089|  if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v1_seen) < 0)))))
 1090|   type = 0x12;
 1091|  else if (((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v2_seen) < 0)))))
 1092|   type = 0x16;
 1093|  else
 1094|   type = 0x22;
 1095|  igmp_send_report(in_dev, im, type);
 1096| }
 1097|
 1098|}
 1099|extern typeof(ip_mc_rejoin_groups) ip_mc_rejoin_groups; extern void *__crc_ip_mc_rejoin_groups ; static const unsigned long __kcrctab_ip_mc_rejoin_groups = (unsigned long) &__crc_ip_mc_rejoin_groups; static const char __kstrtab_ip_mc_rejoin_groups[] = "" "ip_mc_rejoin_groups"; static const struct kernel_symbol __ksymtab_ip_mc_rejoin_groups = { (unsigned long)&ip_mc_rejoin_groups, __kstrtab_ip_mc_rejoin_groups };
 1100|
 1101|
 1102|
 1103|
 1104|
 1105|void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
 1106|{
 1107| struct ip_mc_list *i;
 1108| struct ip_mc_list **ip;
 1109|
 1110| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1315); dump_stack(); } } while(0);
 1111|
 1112| for (ip = &in_dev->mc_list;
 1113|      (i = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1318); } } while (0); ; ((typeof(*(*ip)) *)((*ip))); })) != ((void *)0);
 1114|      ip = &i->next_rcu) {
 1115|  if (i->multiaddr == addr) {
 1116|   if (--i->users == 0) {
 1117|    *ip = i->next_rcu;
 1118|    in_dev->mc_count--;
 1119|    igmp_group_dropped(i);
 1120|
 1121|    if (!in_dev->dead)
 1122|     ip_rt_multicast_event(in_dev);
 1123|
 1124|    ip_ma_put(i);
 1125|    return;
 1126|   }
 1127|   break;
 1128|  }
 1129| }
 1130|}
 1131|extern typeof(ip_mc_dec_group) ip_mc_dec_group; extern void *__crc_ip_mc_dec_group ; static const unsigned long __kcrctab_ip_mc_dec_group = (unsigned long) &__crc_ip_mc_dec_group; static const char __kstrtab_ip_mc_dec_group[] = "" "ip_mc_dec_group"; static const struct kernel_symbol __ksymtab_ip_mc_dec_group = { (unsigned long)&ip_mc_dec_group, __kstrtab_ip_mc_dec_group };
 1132|
 1133|
 1134|
 1135|void ip_mc_unmap(struct in_device *in_dev)
 1136|{
 1137| struct ip_mc_list *pmc;
 1138|
 1139| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1344); dump_stack(); } } while(0);
 1140|
 1141| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1346); } } while (0); ; ((typeof(*(in_dev->mc_list)) *)((in_dev->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1346); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); }))
 1142|  igmp_group_dropped(pmc);
 1143|}
 1144|
 1145|void ip_mc_remap(struct in_device *in_dev)
 1146|{
 1147| struct ip_mc_list *pmc;
 1148|
 1149| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1354); dump_stack(); } } while(0);
 1150|
 1151| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1356); } } while (0); ; ((typeof(*(in_dev->mc_list)) *)((in_dev->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1356); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); }))
 1152|  igmp_group_added(pmc);
 1153|}
 1154|
 1155|
 1156|
 1157|void ip_mc_down(struct in_device *in_dev)
 1158|{
 1159| struct ip_mc_list *pmc;
 1160|
 1161| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1366); dump_stack(); } } while(0);
 1162|
 1163| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1368); } } while (0); ; ((typeof(*(in_dev->mc_list)) *)((in_dev->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1368); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); }))
 1164|  igmp_group_dropped(pmc);
 1165|
 1166|
 1167| in_dev->mr_ifc_count = 0;
 1168| if (del_timer(&in_dev->mr_ifc_timer))
 1169|  atomic_dec(&(in_dev)->refcnt);
 1170| in_dev->mr_gq_running = 0;
 1171| if (del_timer(&in_dev->mr_gq_timer))
 1172|  atomic_dec(&(in_dev)->refcnt);
 1173| igmpv3_clear_delrec(in_dev);
 1174|
 1175|
 1176| ip_mc_dec_group(in_dev, (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))));
 1177|}
 1178|
 1179|void ip_mc_init_dev(struct in_device *in_dev)
 1180|{
 1181| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1386); dump_stack(); } } while(0);
 1182|
 1183| in_dev->mc_tomb = ((void *)0);
 1184|
 1185| in_dev->mr_gq_running = 0;
 1186| do { static struct lock_class_key __key; setup_timer_key((&in_dev->mr_gq_timer), "&in_dev->mr_gq_timer", &__key, (igmp_gq_timer_expire), ((unsigned long)in_dev)); } while (0)
 1187|                         ;
 1188| in_dev->mr_ifc_count = 0;
 1189| in_dev->mc_count = 0;
 1190| do { static struct lock_class_key __key; setup_timer_key((&in_dev->mr_ifc_timer), "&in_dev->mr_ifc_timer", &__key, (igmp_ifc_timer_expire), ((unsigned long)in_dev)); } while (0)
 1191|                         ;
 1192| in_dev->mr_qrv = 2;
 1193|
 1194|
 1195| do { spinlock_check(&in_dev->mc_tomb_lock); do { static struct lock_class_key __key; __raw_spin_lock_init((&(&in_dev->mc_tomb_lock)->rlock), "&(&in_dev->mc_tomb_lock)->rlock", &__key); } while (0); } while (0);
 1196|}
 1197|
 1198|
 1199|
 1200|void ip_mc_up(struct in_device *in_dev)
 1201|{
 1202| struct ip_mc_list *pmc;
 1203|
 1204| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1409); dump_stack(); } } while(0);
 1205|
 1206| ip_mc_inc_group(in_dev, (( __be32)(__builtin_constant_p((__u32)((0xE0000001L))) ? ((__u32)( (((__u32)((0xE0000001L)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0xE0000001L)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0xE0000001L)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0xE0000001L)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0xE0000001L)))));
 1207|
 1208| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1413); } } while (0); ; ((typeof(*(in_dev->mc_list)) *)((in_dev->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1413); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); }))
 1209|  igmp_group_added(pmc);
 1210|}
 1211|
 1212|
 1213|
 1214|
 1215|
 1216|void ip_mc_destroy_dev(struct in_device *in_dev)
 1217|{
 1218| struct ip_mc_list *i;
 1219|
 1220| do { if (__builtin_expect(!!(!rtnl_is_locked()), 0)) { printk("<3>" "RTNL: assertion failed at %s (%d)\n", "net/ipv4/.tmp_igmp.o.armored.c", 1425); dump_stack(); } } while(0);
 1221|
 1222|
 1223| ip_mc_down(in_dev);
 1224|
 1225| while ((i = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1430); } } while (0); ; ((typeof(*(in_dev->mc_list)) *)((in_dev->mc_list))); })) != ((void *)0)) {
 1226|  in_dev->mc_list = i->next_rcu;
 1227|  in_dev->mc_count--;
 1228|
 1229|  igmp_group_dropped(i);
 1230|  ip_ma_put(i);
 1231| }
 1232|}
 1233|
 1234|
 1235|static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
 1236|{
 1237| struct flowi fl = { .nl_u.ip4_u.daddr = imr->imr_multiaddr.s_addr };
 1238| struct rtable *rt;
 1239| struct net_device *dev = ((void *)0);
 1240| struct in_device *idev = ((void *)0);
 1241|
 1242| if (imr->imr_ifindex) {
 1243|  idev = inetdev_by_index(net, imr->imr_ifindex);
 1244|  return idev;
 1245| }
 1246| if (imr->imr_address.s_addr) {
 1247|  dev = __ip_dev_find(net, imr->imr_address.s_addr, false);
 1248|  if (!dev)
 1249|   return ((void *)0);
 1250| }
 1251|
 1252| if (!dev && !ip_route_output_key(net, &rt, &fl)) {
 1253|  dev = rt->dst.dev;
 1254|  ip_rt_put(rt);
 1255| }
 1256| if (dev) {
 1257|  imr->imr_ifindex = dev->ifindex;
 1258|  idev = __in_dev_get_rtnl(dev);
 1259| }
 1260| return idev;
 1261|}
 1262|
 1263|
 1264|
 1265|
 1266|int sysctl_igmp_max_memberships = 20;
 1267|int sysctl_igmp_max_msf = 10;
 1268|
 1269|
 1270|static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
 1271| __be32 *psfsrc)
 1272|{
 1273| struct ip_sf_list *psf, *psf_prev;
 1274| int rv = 0;
 1275|
 1276| psf_prev = ((void *)0);
 1277| for (psf=pmc->sources; psf; psf=psf->sf_next) {
 1278|  if (psf->sf_inaddr == *psfsrc)
 1279|   break;
 1280|  psf_prev = psf;
 1281| }
 1282| if (!psf || psf->sf_count[sfmode] == 0) {
 1283|
 1284|  return -3;
 1285| }
 1286| psf->sf_count[sfmode]--;
 1287| if (psf->sf_count[sfmode] == 0) {
 1288|  ip_rt_multicast_event(pmc->interface);
 1289| }
 1290| if (!psf->sf_count[1] && !psf->sf_count[0]) {
 1291|
 1292|  struct in_device *in_dev = pmc->interface;
 1293|
 1294|
 1295|
 1296|  if (psf_prev)
 1297|   psf_prev->sf_next = psf->sf_next;
 1298|  else
 1299|   pmc->sources = psf->sf_next;
 1300|
 1301|  if (psf->sf_oldin &&
 1302|      !((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v1_seen) < 0)))) && !((((*(dev_net(in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((in_dev)->mr_v2_seen) < 0))))) {
 1303|   psf->sf_crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
 1304|    2;
 1305|   psf->sf_next = pmc->tomb;
 1306|   pmc->tomb = psf;
 1307|   rv = 1;
 1308|  } else
 1309|
 1310|   kfree(psf);
 1311| }
 1312| return rv;
 1313|}
 1314|
 1315|
 1316|
 1317|
 1318|
 1319|static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
 1320|    int sfcount, __be32 *psfsrc, int delta)
 1321|{
 1322| struct ip_mc_list *pmc;
 1323| int changerec = 0;
 1324| int i, err;
 1325|
 1326| if (!in_dev)
 1327|  return -19;
 1328| __st_rcu_read_lock_st__();
 1329| for (pmc = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1534); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); pmc != ((void *)0); pmc = ({ typeof(*(pmc->next_rcu)) *_________p1 = (typeof(*(pmc->next_rcu))* )(*(volatile typeof((pmc->next_rcu)) *)&((pmc->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1534); } } while (0); ; do { } while (0); ((typeof(*(pmc->next_rcu)) *)(_________p1)); })) {
 1330|  if (*pmca == pmc->multiaddr)
 1331|   break;
 1332| }
 1333| if (!pmc) {
 1334|
 1335|  __st_rcu_read_unlock_st__();
 1336|  return -3;
 1337| }
 1338| __st_spin_lock_bh_st__(&pmc->lock);
 1339| __st_rcu_read_unlock_st__();
 1340|
 1341| sf_markstate(pmc);
 1342|
 1343| if (!delta) {
 1344|  err = -22;
 1345|  if (!pmc->sfcount[sfmode])
 1346|   goto out_unlock;
 1347|  pmc->sfcount[sfmode]--;
 1348| }
 1349| err = 0;
 1350| for (i=0; i 1351|  int rv = ip_mc_del1_src(pmc, sfmode, &psfsrc[i]);
 1352|
 1353|  changerec |= rv > 0;
 1354|  if (!err && rv < 0)
 1355|   err = rv;
 1356| }
 1357| if (pmc->sfmode == 0 &&
 1358|     pmc->sfcount[0] == 0 &&
 1359|     pmc->sfcount[1]) {
 1360|
 1361|  struct ip_sf_list *psf;
 1362|
 1363|
 1364|
 1365|  pmc->sfmode = 1;
 1366|
 1367|  pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
 1368|   2;
 1369|  in_dev->mr_ifc_count = pmc->crcount;
 1370|  for (psf=pmc->sources; psf; psf = psf->sf_next)
 1371|   psf->sf_crcount = 0;
 1372|  igmp_ifc_event(pmc->interface);
 1373| } else if (sf_setstate(pmc) || changerec) {
 1374|  igmp_ifc_event(pmc->interface);
 1375|
 1376| }
 1377|out_unlock:
 1378| __st_spin_unlock_bh_st__(&pmc->lock);
 1379| return err;
 1380|}
 1381|
 1382|
 1383|
 1384|
 1385|static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
 1386| __be32 *psfsrc, int delta)
 1387|{
 1388| struct ip_sf_list *psf, *psf_prev;
 1389|
 1390| psf_prev = ((void *)0);
 1391| for (psf=pmc->sources; psf; psf=psf->sf_next) {
 1392|  if (psf->sf_inaddr == *psfsrc)
 1393|   break;
 1394|  psf_prev = psf;
 1395| }
 1396| if (!psf) {
 1397|  psf = kzalloc(sizeof(*psf), ((( gfp_t)0x20u)));
 1398|  if (!psf)
 1399|   return -105;
 1400|  psf->sf_inaddr = *psfsrc;
 1401|  if (psf_prev) {
 1402|   psf_prev->sf_next = psf;
 1403|  } else
 1404|   pmc->sources = psf;
 1405| }
 1406| psf->sf_count[sfmode]++;
 1407| if (psf->sf_count[sfmode] == 1) {
 1408|  ip_rt_multicast_event(pmc->interface);
 1409| }
 1410| return 0;
 1411|}
 1412|
 1413|
 1414|static void sf_markstate(struct ip_mc_list *pmc)
 1415|{
 1416| struct ip_sf_list *psf;
 1417| int mca_xcount = pmc->sfcount[0];
 1418|
 1419| for (psf=pmc->sources; psf; psf=psf->sf_next)
 1420|  if (pmc->sfcount[0]) {
 1421|   psf->sf_oldin = mca_xcount ==
 1422|    psf->sf_count[0] &&
 1423|    !psf->sf_count[1];
 1424|  } else
 1425|   psf->sf_oldin = psf->sf_count[1] != 0;
 1426|}
 1427|
 1428|static int sf_setstate(struct ip_mc_list *pmc)
 1429|{
 1430| struct ip_sf_list *psf, *dpsf;
 1431| int mca_xcount = pmc->sfcount[0];
 1432| int qrv = pmc->interface->mr_qrv;
 1433| int new_in, rv;
 1434|
 1435| rv = 0;
 1436| for (psf=pmc->sources; psf; psf=psf->sf_next) {
 1437|  if (pmc->sfcount[0]) {
 1438|   new_in = mca_xcount == psf->sf_count[0] &&
 1439|    !psf->sf_count[1];
 1440|  } else
 1441|   new_in = psf->sf_count[1] != 0;
 1442|  if (new_in) {
 1443|   if (!psf->sf_oldin) {
 1444|    struct ip_sf_list *prev = ((void *)0);
 1445|
 1446|    for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) {
 1447|     if (dpsf->sf_inaddr == psf->sf_inaddr)
 1448|      break;
 1449|     prev = dpsf;
 1450|    }
 1451|    if (dpsf) {
 1452|     if (prev)
 1453|      prev->sf_next = dpsf->sf_next;
 1454|     else
 1455|      pmc->tomb = dpsf->sf_next;
 1456|     kfree(dpsf);
 1457|    }
 1458|    psf->sf_crcount = qrv;
 1459|    rv++;
 1460|   }
 1461|  } else if (psf->sf_oldin) {
 1462|
 1463|   psf->sf_crcount = 0;
 1464|
 1465|
 1466|
 1467|
 1468|   for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next)
 1469|    if (dpsf->sf_inaddr == psf->sf_inaddr)
 1470|     break;
 1471|   if (!dpsf) {
 1472|    dpsf = kmalloc(sizeof(*dpsf), ((( gfp_t)0x20u)));
 1473|    if (!dpsf)
 1474|     continue;
 1475|    *dpsf = *psf;
 1476|
 1477|    dpsf->sf_next = pmc->tomb;
 1478|    pmc->tomb = dpsf;
 1479|   }
 1480|   dpsf->sf_crcount = qrv;
 1481|   rv++;
 1482|  }
 1483| }
 1484| return rv;
 1485|}
 1486|
 1487|
 1488|
 1489|
 1490|
 1491|static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
 1492|    int sfcount, __be32 *psfsrc, int delta)
 1493|{
 1494| struct ip_mc_list *pmc;
 1495| int isexclude;
 1496| int i, err;
 1497|
 1498| if (!in_dev)
 1499|  return -19;
 1500| __st_rcu_read_lock_st__();
 1501| for (pmc = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1706); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); pmc != ((void *)0); pmc = ({ typeof(*(pmc->next_rcu)) *_________p1 = (typeof(*(pmc->next_rcu))* )(*(volatile typeof((pmc->next_rcu)) *)&((pmc->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1706); } } while (0); ; do { } while (0); ((typeof(*(pmc->next_rcu)) *)(_________p1)); })) {
 1502|  if (*pmca == pmc->multiaddr)
 1503|   break;
 1504| }
 1505| if (!pmc) {
 1506|
 1507|  __st_rcu_read_unlock_st__();
 1508|  return -3;
 1509| }
 1510| __st_spin_lock_bh_st__(&pmc->lock);
 1511| __st_rcu_read_unlock_st__();
 1512|
 1513|
 1514| sf_markstate(pmc);
 1515|
 1516| isexclude = pmc->sfmode == 0;
 1517| if (!delta)
 1518|  pmc->sfcount[sfmode]++;
 1519| err = 0;
 1520| for (i=0; i 1521|  err = ip_mc_add1_src(pmc, sfmode, &psfsrc[i], delta);
 1522|  if (err)
 1523|   break;
 1524| }
 1525| if (err) {
 1526|  int j;
 1527|
 1528|  pmc->sfcount[sfmode]--;
 1529|  for (j=0; j 1530|   (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]);
 1531| } else if (isexclude != (pmc->sfcount[0] != 0)) {
 1532|
 1533|  struct ip_sf_list *psf;
 1534|  in_dev = pmc->interface;
 1535|
 1536|
 1537|
 1538|  if (pmc->sfcount[0])
 1539|   pmc->sfmode = 0;
 1540|  else if (pmc->sfcount[1])
 1541|   pmc->sfmode = 1;
 1542|
 1543|
 1544|
 1545|  pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
 1546|   2;
 1547|  in_dev->mr_ifc_count = pmc->crcount;
 1548|  for (psf=pmc->sources; psf; psf = psf->sf_next)
 1549|   psf->sf_crcount = 0;
 1550|  igmp_ifc_event(in_dev);
 1551| } else if (sf_setstate(pmc)) {
 1552|  igmp_ifc_event(in_dev);
 1553|
 1554| }
 1555| __st_spin_unlock_bh_st__(&pmc->lock);
 1556| return err;
 1557|}
 1558|
 1559|static void ip_mc_clear_src(struct ip_mc_list *pmc)
 1560|{
 1561| struct ip_sf_list *psf, *nextpsf;
 1562|
 1563| for (psf=pmc->tomb; psf; psf=nextpsf) {
 1564|  nextpsf = psf->sf_next;
 1565|  kfree(psf);
 1566| }
 1567| pmc->tomb = ((void *)0);
 1568| for (psf=pmc->sources; psf; psf=nextpsf) {
 1569|  nextpsf = psf->sf_next;
 1570|  kfree(psf);
 1571| }
 1572| pmc->sources = ((void *)0);
 1573| pmc->sfmode = 0;
 1574| pmc->sfcount[1] = 0;
 1575| pmc->sfcount[0] = 1;
 1576|}
 1577|
 1578|
 1579|
 1580|
 1581|
 1582|int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
 1583|{
 1584| int err;
 1585| __be32 addr = imr->imr_multiaddr.s_addr;
 1586| struct ip_mc_socklist *iml = ((void *)0), *i;
 1587| struct in_device *in_dev;
 1588| struct inet_sock *inet = inet_sk(sk);
 1589| struct net *net = sock_net(sk);
 1590| int ifindex;
 1591| int count = 0;
 1592|
 1593| if (!ipv4_is_multicast(addr))
 1594|  return -22;
 1595|
 1596| rtnl_lock();
 1597|
 1598| in_dev = ip_mc_find_dev(net, imr);
 1599|
 1600| if (!in_dev) {
 1601|  iml = ((void *)0);
 1602|  err = -19;
 1603|  goto done;
 1604| }
 1605|
 1606| err = -98;
 1607| ifindex = imr->imr_ifindex;
 1608| for (i = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1813); } } while (0); ; ((typeof(*(inet->mc_list)) *)((inet->mc_list))); }); i != ((void *)0); i = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1813); } } while (0); ; ((typeof(*(i->next_rcu)) *)((i->next_rcu))); })) {
 1609|  if (i->multi.imr_multiaddr.s_addr == addr &&
 1610|      i->multi.imr_ifindex == ifindex)
 1611|   goto done;
 1612|  count++;
 1613| }
 1614| err = -105;
 1615| if (count >= sysctl_igmp_max_memberships)
 1616|  goto done;
 1617| iml = sock_kmalloc(sk, sizeof(*iml), __st_GFP_KERNEL_st__);
 1618| if (iml == ((void *)0))
 1619|  goto done;
 1620|
 1621| __st_memcpy_st__(&iml->multi, imr, sizeof(*imr));
 1622| iml->next_rcu = inet->mc_list;
 1623| iml->sflist = ((void *)0);
 1624| iml->sfmode = 0;
 1625| __st_rcu_assign_pointer_st__(inet->mc_list, iml);
 1626| ip_mc_inc_group(in_dev, addr);
 1627| err = 0;
 1628|done:
 1629| rtnl_unlock();
 1630| return err;
 1631|}
 1632|extern typeof(ip_mc_join_group) ip_mc_join_group; extern void *__crc_ip_mc_join_group ; static const unsigned long __kcrctab_ip_mc_join_group = (unsigned long) &__crc_ip_mc_join_group; static const char __kstrtab_ip_mc_join_group[] = "" "ip_mc_join_group"; static const struct kernel_symbol __ksymtab_ip_mc_join_group = { (unsigned long)&ip_mc_join_group, __kstrtab_ip_mc_join_group };
 1633|
 1634|static void ip_sf_socklist_reclaim(struct rcu_head *rp)
 1635|{
 1636| kfree(({ const typeof( ((struct ip_sf_socklist *)0)->rcu ) *__mptr = (rp); (struct ip_sf_socklist *)( (char *)__mptr - 1 );}));
 1637|
 1638|}
 1639|
 1640|static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
 1641|      struct in_device *in_dev)
 1642|{
 1643| struct ip_sf_socklist *psf = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1848); } } while (0); ; ((typeof(*(iml->sflist)) *)((iml->sflist))); });
 1644| int err;
 1645|
 1646| if (psf == ((void *)0)) {
 1647|
 1648|  return ip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr,
 1649|   iml->sfmode, 0, ((void *)0), 0);
 1650| }
 1651| err = ip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr,
 1652|   iml->sfmode, psf->sl_count, psf->sl_addr, 0);
 1653| __st_rcu_assign_pointer_st__(iml->sflist, ((void *)0));
 1654|
 1655| atomic_sub((sizeof(struct ip_sf_socklist) + (psf->sl_max) * sizeof(__be32)), &sk->sk_omem_alloc);
 1656| call_rcu_sched(&psf->rcu, ip_sf_socklist_reclaim);
 1657| return err;
 1658|}
 1659|
 1660|
 1661|static void ip_mc_socklist_reclaim(struct rcu_head *rp)
 1662|{
 1663| kfree(({ const typeof( ((struct ip_mc_socklist *)0)->rcu ) *__mptr = (rp); (struct ip_mc_socklist *)( (char *)__mptr - 1 );}));
 1664|
 1665|}
 1666|
 1667|
 1668|
 1669|
 1670|
 1671|
 1672|int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
 1673|{
 1674| struct inet_sock *inet = inet_sk(sk);
 1675| struct ip_mc_socklist *iml;
 1676| struct ip_mc_socklist **imlp;
 1677| struct in_device *in_dev;
 1678| struct net *net = sock_net(sk);
 1679| __be32 group = imr->imr_multiaddr.s_addr;
 1680| u32 ifindex;
 1681| int ret = -99;
 1682|
 1683| rtnl_lock();
 1684| in_dev = ip_mc_find_dev(net, imr);
 1685| ifindex = imr->imr_ifindex;
 1686| for (imlp = &inet->mc_list;
 1687|      (iml = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1892); } } while (0); ; ((typeof(*(*imlp)) *)((*imlp))); })) != ((void *)0);
 1688|      imlp = &iml->next_rcu) {
 1689|  if (iml->multi.imr_multiaddr.s_addr != group)
 1690|   continue;
 1691|  if (ifindex) {
 1692|   if (iml->multi.imr_ifindex != ifindex)
 1693|    continue;
 1694|  } else if (imr->imr_address.s_addr && imr->imr_address.s_addr !=
 1695|    iml->multi.imr_address.s_addr)
 1696|   continue;
 1697|
 1698|  (void) ip_mc_leave_src(sk, iml, in_dev);
 1699|
 1700|  *imlp = iml->next_rcu;
 1701|
 1702|  if (in_dev)
 1703|   ip_mc_dec_group(in_dev, group);
 1704|  rtnl_unlock();
 1705|
 1706|  atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
 1707|  call_rcu_sched(&iml->rcu, ip_mc_socklist_reclaim);
 1708|  return 0;
 1709| }
 1710| if (!in_dev)
 1711|  ret = -19;
 1712| rtnl_unlock();
 1713| return ret;
 1714|}
 1715|
 1716|int ip_mc_source(int add, int omode, struct sock *sk, struct
 1717| ip_mreq_source *mreqs, int ifindex)
 1718|{
 1719| int err;
 1720| struct ip_mreqn imr;
 1721| __be32 addr = mreqs->imr_multiaddr;
 1722| struct ip_mc_socklist *pmc;
 1723| struct in_device *in_dev = ((void *)0);
 1724| struct inet_sock *inet = inet_sk(sk);
 1725| struct ip_sf_socklist *psl;
 1726| struct net *net = sock_net(sk);
 1727| int leavegroup = 0;
 1728| int i, j, rv;
 1729|
 1730| if (!ipv4_is_multicast(addr))
 1731|  return -22;
 1732|
 1733| rtnl_lock();
 1734|
 1735| imr.imr_multiaddr.s_addr = mreqs->imr_multiaddr;
 1736| imr.imr_address.s_addr = mreqs->imr_interface;
 1737| imr.imr_ifindex = ifindex;
 1738| in_dev = ip_mc_find_dev(net, &imr);
 1739|
 1740| if (!in_dev) {
 1741|  err = -19;
 1742|  goto done;
 1743| }
 1744| err = -99;
 1745|
 1746| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1951); } } while (0); ; ((typeof(*(inet->mc_list)) *)((inet->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1951); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); })) {
 1747|  if ((pmc->multi.imr_multiaddr.s_addr ==
 1748|       imr.imr_multiaddr.s_addr) &&
 1749|      (pmc->multi.imr_ifindex == imr.imr_ifindex))
 1750|   break;
 1751| }
 1752| if (!pmc) {
 1753|  err = -22;
 1754|  goto done;
 1755| }
 1756|
 1757| if (pmc->sflist) {
 1758|  if (pmc->sfmode != omode) {
 1759|   err = -22;
 1760|   goto done;
 1761|  }
 1762| } else if (pmc->sfmode != omode) {
 1763|
 1764|  ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, ((void *)0), 0);
 1765|  ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0,
 1766|   ((void *)0), 0);
 1767|  pmc->sfmode = omode;
 1768| }
 1769|
 1770| psl = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 1975); } } while (0); ; ((typeof(*(pmc->sflist)) *)((pmc->sflist))); });
 1771| if (!add) {
 1772|  if (!psl)
 1773|   goto done;
 1774|  rv = !0;
 1775|  for (i=0; isl_count; i++) {
 1776|   rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
 1777|    sizeof(__be32));
 1778|   if (rv == 0)
 1779|    break;
 1780|  }
 1781|  if (rv)
 1782|   goto done;
 1783|
 1784|
 1785|  if (psl->sl_count == 1 && omode == 1) {
 1786|   leavegroup = 1;
 1787|   goto done;
 1788|  }
 1789|
 1790|
 1791|  ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
 1792|   &mreqs->imr_sourceaddr, 1);
 1793|
 1794|  for (j=i+1; jsl_count; j++)
 1795|   psl->sl_addr[j-1] = psl->sl_addr[j];
 1796|  psl->sl_count--;
 1797|  err = 0;
 1798|  goto done;
 1799| }
 1800|
 1801|
 1802| if (psl && psl->sl_count >= sysctl_igmp_max_msf) {
 1803|  err = -105;
 1804|  goto done;
 1805| }
 1806| if (!psl || psl->sl_count == psl->sl_max) {
 1807|  struct ip_sf_socklist *newpsl;
 1808|  int count = 10;
 1809|
 1810|  if (psl)
 1811|   count += psl->sl_max;
 1812|  newpsl = sock_kmalloc(sk, (sizeof(struct ip_sf_socklist) + (count) * sizeof(__be32)), __st_GFP_KERNEL_st__);
 1813|  if (!newpsl) {
 1814|   err = -105;
 1815|   goto done;
 1816|  }
 1817|  newpsl->sl_max = count;
 1818|  newpsl->sl_count = count - 10;
 1819|  if (psl) {
 1820|   for (i=0; isl_count; i++)
 1821|    newpsl->sl_addr[i] = psl->sl_addr[i];
 1822|
 1823|   atomic_sub((sizeof(struct ip_sf_socklist) + (psl->sl_max) * sizeof(__be32)), &sk->sk_omem_alloc);
 1824|   call_rcu_sched(&psl->rcu, ip_sf_socklist_reclaim);
 1825|  }
 1826|  __st_rcu_assign_pointer_st__(pmc->sflist, newpsl);
 1827|  psl = newpsl;
 1828| }
 1829| rv = 1;
 1830| for (i=0; isl_count; i++) {
 1831|  rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
 1832|   sizeof(__be32));
 1833|  if (rv == 0)
 1834|   break;
 1835| }
 1836| if (rv == 0)
 1837|  goto done;
 1838| for (j=psl->sl_count-1; j>=i; j--)
 1839|  psl->sl_addr[j+1] = psl->sl_addr[j];
 1840| psl->sl_addr[i] = mreqs->imr_sourceaddr;
 1841| psl->sl_count++;
 1842| err = 0;
 1843|
 1844| ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
 1845|  &mreqs->imr_sourceaddr, 1);
 1846|done:
 1847| rtnl_unlock();
 1848| if (leavegroup)
 1849|  return ip_mc_leave_group(sk, &imr);
 1850| return err;
 1851|}
 1852|
 1853|int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
 1854|{
 1855| int err = 0;
 1856| struct ip_mreqn imr;
 1857| __be32 addr = msf->imsf_multiaddr;
 1858| struct ip_mc_socklist *pmc;
 1859| struct in_device *in_dev;
 1860| struct inet_sock *inet = inet_sk(sk);
 1861| struct ip_sf_socklist *newpsl, *psl;
 1862| struct net *net = sock_net(sk);
 1863| int leavegroup = 0;
 1864|
 1865| if (!ipv4_is_multicast(addr))
 1866|  return -22;
 1867| if (msf->imsf_fmode != 1 &&
 1868|     msf->imsf_fmode != 0)
 1869|  return -22;
 1870|
 1871| rtnl_lock();
 1872|
 1873| imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
 1874| imr.imr_address.s_addr = msf->imsf_interface;
 1875| imr.imr_ifindex = ifindex;
 1876| in_dev = ip_mc_find_dev(net, &imr);
 1877|
 1878| if (!in_dev) {
 1879|  err = -19;
 1880|  goto done;
 1881| }
 1882|
 1883|
 1884| if (msf->imsf_fmode == 1 && msf->imsf_numsrc == 0) {
 1885|  leavegroup = 1;
 1886|  goto done;
 1887| }
 1888|
 1889| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2094); } } while (0); ; ((typeof(*(inet->mc_list)) *)((inet->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2094); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); })) {
 1890|  if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
 1891|      pmc->multi.imr_ifindex == imr.imr_ifindex)
 1892|   break;
 1893| }
 1894| if (!pmc) {
 1895|  err = -22;
 1896|  goto done;
 1897| }
 1898| if (msf->imsf_numsrc) {
 1899|  newpsl = sock_kmalloc(sk, (sizeof(struct ip_sf_socklist) + (msf->imsf_numsrc) * sizeof(__be32)),
 1900|          __st_GFP_KERNEL_st__);
 1901|  if (!newpsl) {
 1902|   err = -105;
 1903|   goto done;
 1904|  }
 1905|  newpsl->sl_max = newpsl->sl_count = msf->imsf_numsrc;
 1906|  __st_memcpy_st__(newpsl->sl_addr, msf->imsf_slist,
 1907|   msf->imsf_numsrc * sizeof(msf->imsf_slist[0]));
 1908|  err = ip_mc_add_src(in_dev, &msf->imsf_multiaddr,
 1909|   msf->imsf_fmode, newpsl->sl_count, newpsl->sl_addr, 0);
 1910|  if (err) {
 1911|   sock_kfree_s(sk, newpsl, (sizeof(struct ip_sf_socklist) + (newpsl->sl_max) * sizeof(__be32)));
 1912|   goto done;
 1913|  }
 1914| } else {
 1915|  newpsl = ((void *)0);
 1916|  (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr,
 1917|         msf->imsf_fmode, 0, ((void *)0), 0);
 1918| }
 1919| psl = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2124); } } while (0); ; ((typeof(*(pmc->sflist)) *)((pmc->sflist))); });
 1920| if (psl) {
 1921|  (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
 1922|   psl->sl_count, psl->sl_addr, 0);
 1923|
 1924|  atomic_sub((sizeof(struct ip_sf_socklist) + (psl->sl_max) * sizeof(__be32)), &sk->sk_omem_alloc);
 1925|  call_rcu_sched(&psl->rcu, ip_sf_socklist_reclaim);
 1926| } else
 1927|  (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
 1928|   0, ((void *)0), 0);
 1929| __st_rcu_assign_pointer_st__(pmc->sflist, newpsl);
 1930| pmc->sfmode = msf->imsf_fmode;
 1931| err = 0;
 1932|done:
 1933| rtnl_unlock();
 1934| if (leavegroup)
 1935|  err = ip_mc_leave_group(sk, &imr);
 1936| return err;
 1937|}
 1938|
 1939|int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
 1940| struct ip_msfilter *optval, int *optlen)
 1941|{
 1942| int err, len, count, copycount;
 1943| struct ip_mreqn imr;
 1944| __be32 addr = msf->imsf_multiaddr;
 1945| struct ip_mc_socklist *pmc;
 1946| struct in_device *in_dev;
 1947| struct inet_sock *inet = inet_sk(sk);
 1948| struct ip_sf_socklist *psl;
 1949| struct net *net = sock_net(sk);
 1950|
 1951| if (!ipv4_is_multicast(addr))
 1952|  return -22;
 1953|
 1954| rtnl_lock();
 1955|
 1956| imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
 1957| imr.imr_address.s_addr = msf->imsf_interface;
 1958| imr.imr_ifindex = 0;
 1959| in_dev = ip_mc_find_dev(net, &imr);
 1960|
 1961| if (!in_dev) {
 1962|  err = -19;
 1963|  goto done;
 1964| }
 1965| err = -99;
 1966|
 1967| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2172); } } while (0); ; ((typeof(*(inet->mc_list)) *)((inet->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2172); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); })) {
 1968|  if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
 1969|      pmc->multi.imr_ifindex == imr.imr_ifindex)
 1970|   break;
 1971| }
 1972| if (!pmc)
 1973|  goto done;
 1974| msf->imsf_fmode = pmc->sfmode;
 1975| psl = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2180); } } while (0); ; ((typeof(*(pmc->sflist)) *)((pmc->sflist))); });
 1976| rtnl_unlock();
 1977| if (!psl) {
 1978|  len = 0;
 1979|  count = 0;
 1980| } else {
 1981|  count = psl->sl_count;
 1982| }
 1983| copycount = count < msf->imsf_numsrc ? count : msf->imsf_numsrc;
 1984| len = copycount * sizeof(psl->sl_addr[0]);
 1985| msf->imsf_numsrc = count;
 1986| if (__st_put_user_st__((sizeof(struct ip_msfilter) - sizeof(__u32) + (copycount) * sizeof(__u32)), optlen) ||
 1987|     copy_to_user(optval, msf, (sizeof(struct ip_msfilter) - sizeof(__u32) + (0) * sizeof(__u32)))) {
 1988|  return -14;
 1989| }
 1990| if (len &&
 1991|     copy_to_user(&optval->imsf_slist[0], psl->sl_addr, len))
 1992|  return -14;
 1993| return 0;
 1994|done:
 1995| rtnl_unlock();
 1996| return err;
 1997|}
 1998|
 1999|int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
 2000| struct group_filter *optval, int *optlen)
 2001|{
 2002| int err, i, count, copycount;
 2003| struct sockaddr_in *psin;
 2004| __be32 addr;
 2005| struct ip_mc_socklist *pmc;
 2006| struct inet_sock *inet = inet_sk(sk);
 2007| struct ip_sf_socklist *psl;
 2008|
 2009| psin = (struct sockaddr_in *)&gsf->gf_group;
 2010| if (psin->sin_family != 2)
 2011|  return -22;
 2012| addr = psin->sin_addr.s_addr;
 2013| if (!ipv4_is_multicast(addr))
 2014|  return -22;
 2015|
 2016| rtnl_lock();
 2017|
 2018| err = -99;
 2019|
 2020| for (pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2225); } } while (0); ; ((typeof(*(inet->mc_list)) *)((inet->mc_list))); }); pmc != ((void *)0); pmc = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2225); } } while (0); ; ((typeof(*(pmc->next_rcu)) *)((pmc->next_rcu))); })) {
 2021|  if (pmc->multi.imr_multiaddr.s_addr == addr &&
 2022|      pmc->multi.imr_ifindex == gsf->gf_interface)
 2023|   break;
 2024| }
 2025| if (!pmc)
 2026|  goto done;
 2027| gsf->gf_fmode = pmc->sfmode;
 2028| psl = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2233); } } while (0); ; ((typeof(*(pmc->sflist)) *)((pmc->sflist))); });
 2029| rtnl_unlock();
 2030| count = psl ? psl->sl_count : 0;
 2031| copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
 2032| gsf->gf_numsrc = count;
 2033| if (__st_put_user_st__((sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (copycount) * sizeof(struct __kernel_sockaddr_storage)), optlen) ||
 2034|     copy_to_user(optval, gsf, (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (0) * sizeof(struct __kernel_sockaddr_storage)))) {
 2035|  return -14;
 2036| }
 2037| for (i=0; i 2038|  struct __kernel_sockaddr_storage ss;
 2039|
 2040|  psin = (struct sockaddr_in *)&ss;
 2041|  __st_memset_st__(&ss, 0, sizeof(ss));
 2042|  psin->sin_family = 2;
 2043|  psin->sin_addr.s_addr = psl->sl_addr[i];
 2044|  if (copy_to_user(&optval->gf_slist[i], &ss, sizeof(ss)))
 2045|   return -14;
 2046| }
 2047| return 0;
 2048|done:
 2049| rtnl_unlock();
 2050| return err;
 2051|}
 2052|
 2053|
 2054|
 2055|
 2056|int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
 2057|{
 2058| struct inet_sock *inet = inet_sk(sk);
 2059| struct ip_mc_socklist *pmc;
 2060| struct ip_sf_socklist *psl;
 2061| int i;
 2062| int ret;
 2063|
 2064| ret = 1;
 2065| if (!ipv4_is_multicast(loc_addr))
 2066|  goto out;
 2067|
 2068| __st_rcu_read_lock_st__();
 2069| for (pmc = ({ typeof(*(inet->mc_list)) *_________p1 = (typeof(*(inet->mc_list))* )(*(volatile typeof((inet->mc_list)) *)&((inet->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2274); } } while (0); ; do { } while (0); ((typeof(*(inet->mc_list)) *)(_________p1)); }); pmc != ((void *)0); pmc = ({ typeof(*(pmc->next_rcu)) *_________p1 = (typeof(*(pmc->next_rcu))* )(*(volatile typeof((pmc->next_rcu)) *)&((pmc->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2274); } } while (0); ; do { } while (0); ((typeof(*(pmc->next_rcu)) *)(_________p1)); })) {
 2070|  if (pmc->multi.imr_multiaddr.s_addr == loc_addr &&
 2071|      pmc->multi.imr_ifindex == dif)
 2072|   break;
 2073| }
 2074| ret = inet->mc_all;
 2075| if (!pmc)
 2076|  goto unlock;
 2077| psl = ({ typeof(*(pmc->sflist)) *_________p1 = (typeof(*(pmc->sflist))* )(*(volatile typeof((pmc->sflist)) *)&((pmc->sflist))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2282); } } while (0); ; do { } while (0); ((typeof(*(pmc->sflist)) *)(_________p1)); });
 2078| ret = (pmc->sfmode == 0);
 2079| if (!psl)
 2080|  goto unlock;
 2081|
 2082| for (i=0; isl_count; i++) {
 2083|  if (psl->sl_addr[i] == rmt_addr)
 2084|   break;
 2085| }
 2086| ret = 0;
 2087| if (pmc->sfmode == 1 && i >= psl->sl_count)
 2088|  goto unlock;
 2089| if (pmc->sfmode == 0 && i < psl->sl_count)
 2090|  goto unlock;
 2091| ret = 1;
 2092|unlock:
 2093| __st_rcu_read_unlock_st__();
 2094|out:
 2095| return ret;
 2096|}
 2097|
 2098|
 2099|
 2100|
 2101|
 2102|void ip_mc_drop_socket(struct sock *sk)
 2103|{
 2104| struct inet_sock *inet = inet_sk(sk);
 2105| struct ip_mc_socklist *iml;
 2106| struct net *net = sock_net(sk);
 2107|
 2108| if (inet->mc_list == ((void *)0))
 2109|  return;
 2110|
 2111| rtnl_lock();
 2112| while ((iml = ({ do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !((lockdep_rtnl_is_held()))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2317); } } while (0); ; ((typeof(*(inet->mc_list)) *)((inet->mc_list))); })) != ((void *)0)) {
 2113|  struct in_device *in_dev;
 2114|
 2115|  inet->mc_list = iml->next_rcu;
 2116|  in_dev = inetdev_by_index(net, iml->multi.imr_ifindex);
 2117|  (void) ip_mc_leave_src(sk, iml, in_dev);
 2118|  if (in_dev != ((void *)0))
 2119|   ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
 2120|
 2121|  atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
 2122|  call_rcu_sched(&iml->rcu, ip_mc_socklist_reclaim);
 2123| }
 2124| rtnl_unlock();
 2125|}
 2126|
 2127|int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 proto)
 2128|{
 2129| struct ip_mc_list *im;
 2130| struct ip_sf_list *psf;
 2131| int rv = 0;
 2132|
 2133| __st_rcu_read_lock_st__();
 2134| for (im = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2339); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); }); im != ((void *)0); im = ({ typeof(*(im->next_rcu)) *_________p1 = (typeof(*(im->next_rcu))* )(*(volatile typeof((im->next_rcu)) *)&((im->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2339); } } while (0); ; do { } while (0); ((typeof(*(im->next_rcu)) *)(_________p1)); })) {
 2135|  if (im->multiaddr == mc_addr)
 2136|   break;
 2137| }
 2138| if (im && proto == IPPROTO_IGMP) {
 2139|  rv = 1;
 2140| } else if (im) {
 2141|  if (src_addr) {
 2142|   for (psf=im->sources; psf; psf=psf->sf_next) {
 2143|    if (psf->sf_inaddr == src_addr)
 2144|     break;
 2145|   }
 2146|   if (psf)
 2147|    rv = psf->sf_count[1] ||
 2148|     psf->sf_count[0] !=
 2149|     im->sfcount[0];
 2150|   else
 2151|    rv = im->sfcount[0] != 0;
 2152|  } else
 2153|   rv = 1;
 2154| }
 2155| __st_rcu_read_unlock_st__();
 2156| return rv;
 2157|}
 2158|
 2159|
 2160|struct igmp_mc_iter_state {
 2161| struct seq_net_private p;
 2162| struct net_device *dev;
 2163| struct in_device *in_dev;
 2164|};
 2165|
 2166|
 2167|
 2168|static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
 2169|{
 2170| struct net *net = seq_file_net(seq);
 2171| struct ip_mc_list *im = ((void *)0);
 2172| struct igmp_mc_iter_state *state = ((struct igmp_mc_iter_state *)(seq)->private);
 2173|
 2174| state->in_dev = ((void *)0);
 2175| for (state->dev = ({typeof (*(&(net)->dev_base_head)->next) *__ptr = (typeof (*(&(net)->dev_base_head)->next) *)(&(net)->dev_base_head)->next; ({ const typeof( ((typeof(*state->dev) *)0)->dev_list ) *__mptr = ((typeof((&(net)->dev_base_head)->next))({ typeof(*(__ptr)) *_________p1 = (typeof(*(__ptr))* )(*(volatile typeof((__ptr)) *)&((__ptr))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (1))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2380); } } while (0); ; do { } while (0); ((typeof(*(__ptr)) *)(_________p1)); })); (typeof(*state->dev) *)( (char *)__mptr - 1 );}); }); __builtin_prefetch(state->dev->dev_list.next), &state->dev->dev_list != (&(net)->dev_base_head); state->dev = ({typeof (*state->dev->dev_list.next) *__ptr = (typeof (*state->dev->dev_list.next) *)state->dev->dev_list.next; ({ const typeof( ((typeof(*state->dev) *)0)->dev_list ) *__mptr = ((typeof(state->dev->dev_list.next))({ typeof(*(__ptr)) *_________p1 = (typeof(*(__ptr))* )(*(volatile typeof((__ptr)) *)&((__ptr))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (1))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2380); } } while (0); ; do { } while (0); ((typeof(*(__ptr)) *)(_________p1)); })); (typeof(*state->dev) *)( (char *)__mptr - 1 );}); })) {
 2176|  struct in_device *in_dev;
 2177|
 2178|  in_dev = __in_dev_get_rcu(state->dev);
 2179|  if (!in_dev)
 2180|   continue;
 2181|  im = ({ typeof(*(in_dev->mc_list)) *_________p1 = (typeof(*(in_dev->mc_list))* )(*(volatile typeof((in_dev->mc_list)) *)&((in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2386); } } while (0); ; do { } while (0); ((typeof(*(in_dev->mc_list)) *)(_________p1)); });
 2182|  if (im) {
 2183|   state->in_dev = in_dev;
 2184|   break;
 2185|  }
 2186| }
 2187| return im;
 2188|}
 2189|
 2190|static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im)
 2191|{
 2192| struct igmp_mc_iter_state *state = ((struct igmp_mc_iter_state *)(seq)->private);
 2193|
 2194| im = ({ typeof(*(im->next_rcu)) *_________p1 = (typeof(*(im->next_rcu))* )(*(volatile typeof((im->next_rcu)) *)&((im->next_rcu))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2399); } } while (0); ; do { } while (0); ((typeof(*(im->next_rcu)) *)(_________p1)); });
 2195| while (!im) {
 2196|  state->dev = next_net_device_rcu(state->dev);
 2197|  if (!state->dev) {
 2198|   state->in_dev = ((void *)0);
 2199|   break;
 2200|  }
 2201|  state->in_dev = __in_dev_get_rcu(state->dev);
 2202|  if (!state->in_dev)
 2203|   continue;
 2204|  im = ({ typeof(*(state->in_dev->mc_list)) *_________p1 = (typeof(*(state->in_dev->mc_list))* )(*(volatile typeof((state->in_dev->mc_list)) *)&((state->in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2409); } } while (0); ; do { } while (0); ((typeof(*(state->in_dev->mc_list)) *)(_________p1)); });
 2205| }
 2206| return im;
 2207|}
 2208|
 2209|static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos)
 2210|{
 2211| struct ip_mc_list *im = igmp_mc_get_first(seq);
 2212| if (im)
 2213|  while (pos && (im = igmp_mc_get_next(seq, im)) != ((void *)0))
 2214|   --pos;
 2215| return pos ? ((void *)0) : im;
 2216|}
 2217|
 2218|static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
 2219|
 2220|{
 2221| __st_rcu_read_lock_st__();
 2222| return *pos ? igmp_mc_get_idx(seq, *pos - 1) : ((void *)1);
 2223|}
 2224|
 2225|static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 2226|{
 2227| struct ip_mc_list *im;
 2228| if (v == ((void *)1))
 2229|  im = igmp_mc_get_first(seq);
 2230| else
 2231|  im = igmp_mc_get_next(seq, v);
 2232| ++*pos;
 2233| return im;
 2234|}
 2235|
 2236|static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
 2237|
 2238|{
 2239| struct igmp_mc_iter_state *state = ((struct igmp_mc_iter_state *)(seq)->private);
 2240|
 2241| state->in_dev = ((void *)0);
 2242| state->dev = ((void *)0);
 2243| __st_rcu_read_unlock_st__();
 2244|}
 2245|
 2246|static int igmp_mc_seq_show(struct seq_file *seq, void *v)
 2247|{
 2248| if (v == ((void *)1))
 2249|  seq_puts(seq,
 2250|    "Idx\tDevice    : Count Querier\tGroup    Users Timer\tReporter\n");
 2251| else {
 2252|  struct ip_mc_list *im = (struct ip_mc_list *)v;
 2253|  struct igmp_mc_iter_state *state = ((struct igmp_mc_iter_state *)(seq)->private);
 2254|  char *querier;
 2255|
 2256|  querier = ((((*(dev_net(state->in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 1 || ipv4_devconf_get(((state->in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 1 || ((state->in_dev)->mr_v1_seen && (({ unsigned long __dummy; typeof((state->in_dev)->mr_v1_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((state->in_dev)->mr_v1_seen) < 0)))) ? "V1" :
 2257|     ((((*(dev_net(state->in_dev->dev))->ipv4.devconf_all)).data[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]) == 2 || ipv4_devconf_get(((state->in_dev)), IPV4_DEVCONF_FORCE_IGMP_VERSION) == 2 || ((state->in_dev)->mr_v2_seen && (({ unsigned long __dummy; typeof((state->in_dev)->mr_v2_seen) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)((state->in_dev)->mr_v2_seen) < 0)))) ? "V2" :
 2258|     "V3";
 2259|
 2260|
 2261|
 2262|
 2263|  if (({ typeof(*(state->in_dev->mc_list)) *_________p1 = (typeof(*(state->in_dev->mc_list))* )(*(volatile typeof((state->in_dev->mc_list)) *)&((state->in_dev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2468); } } while (0); ; do { } while (0); ((typeof(*(state->in_dev->mc_list)) *)(_________p1)); }) == im) {
 2264|   seq_printf(seq, "%d\t%-10s: %5d %7s\n",
 2265|       state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier);
 2266|  }
 2267|
 2268|  seq_printf(seq,
 2269|      "\t\t\t\t%08X %5d %d:%08lX\t\t%d\n",
 2270|      im->multiaddr, im->users,
 2271|      im->tm_running, im->tm_running ?
 2272|      jiffies_to_clock_t(im->timer.expires-jiffies) : 0,
 2273|      im->reporter);
 2274| }
 2275| return 0;
 2276|}
 2277|
 2278|static const struct seq_operations igmp_mc_seq_ops = {
 2279| .start = igmp_mc_seq_start,
 2280| .next = igmp_mc_seq_next,
 2281| .stop = igmp_mc_seq_stop,
 2282| .show = igmp_mc_seq_show,
 2283|};
 2284|
 2285|static int igmp_mc_seq_open(struct inode *inode, struct file *file)
 2286|{
 2287| return seq_open_net(inode, file, &igmp_mc_seq_ops,
 2288|   sizeof(struct igmp_mc_iter_state));
 2289|}
 2290|
 2291|static const struct file_operations igmp_mc_seq_fops = {
 2292| .owner = ((struct module *)0),
 2293| .open = igmp_mc_seq_open,
 2294| .read = seq_read,
 2295| .llseek = seq_lseek,
 2296| .release = seq_release_net,
 2297|};
 2298|
 2299|struct igmp_mcf_iter_state {
 2300| struct seq_net_private p;
 2301| struct net_device *dev;
 2302| struct in_device *idev;
 2303| struct ip_mc_list *im;
 2304|};
 2305|
 2306|
 2307|
 2308|static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
 2309|{
 2310| struct net *net = seq_file_net(seq);
 2311| struct ip_sf_list *psf = ((void *)0);
 2312| struct ip_mc_list *im = ((void *)0);
 2313| struct igmp_mcf_iter_state *state = ((struct igmp_mcf_iter_state *)(seq)->private);
 2314|
 2315| state->idev = ((void *)0);
 2316| state->im = ((void *)0);
 2317| for (state->dev = ({typeof (*(&(net)->dev_base_head)->next) *__ptr = (typeof (*(&(net)->dev_base_head)->next) *)(&(net)->dev_base_head)->next; ({ const typeof( ((typeof(*state->dev) *)0)->dev_list ) *__mptr = ((typeof((&(net)->dev_base_head)->next))({ typeof(*(__ptr)) *_________p1 = (typeof(*(__ptr))* )(*(volatile typeof((__ptr)) *)&((__ptr))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (1))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2522); } } while (0); ; do { } while (0); ((typeof(*(__ptr)) *)(_________p1)); })); (typeof(*state->dev) *)( (char *)__mptr - 1 );}); }); __builtin_prefetch(state->dev->dev_list.next), &state->dev->dev_list != (&(net)->dev_base_head); state->dev = ({typeof (*state->dev->dev_list.next) *__ptr = (typeof (*state->dev->dev_list.next) *)state->dev->dev_list.next; ({ const typeof( ((typeof(*state->dev) *)0)->dev_list ) *__mptr = ((typeof(state->dev->dev_list.next))({ typeof(*(__ptr)) *_________p1 = (typeof(*(__ptr))* )(*(volatile typeof((__ptr)) *)&((__ptr))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (1))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2522); } } while (0); ; do { } while (0); ((typeof(*(__ptr)) *)(_________p1)); })); (typeof(*state->dev) *)( (char *)__mptr - 1 );}); })) {
 2318|  struct in_device *idev;
 2319|  idev = __in_dev_get_rcu(state->dev);
 2320|  if (idev == ((void *)0))
 2321|   continue;
 2322|  im = ({ typeof(*(idev->mc_list)) *_________p1 = (typeof(*(idev->mc_list))* )(*(volatile typeof((idev->mc_list)) *)&((idev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2527); } } while (0); ; do { } while (0); ((typeof(*(idev->mc_list)) *)(_________p1)); });
 2323|  if (im != ((void *)0)) {
 2324|   __st_spin_lock_bh_st__(&im->lock);
     |The lock is locked here. prev next
 2325|   psf = im->sources;
     |not affected ==> the lock is still locked. prev next
 2326|   if (psf != ((void *)0)) {
     |not affected ==> the lock is still locked. prev next
 2327|    state->im = im;
     |not affected ==> the lock is still locked. prev next
 2328|    state->idev = idev;
     |not affected ==> the lock is still locked. prev next
 2329|    break;
     |not affected ==> the lock is still locked. prev next
 2330|   }
 2331|   __st_spin_unlock_bh_st__(&im->lock);
 2332|  }
 2333| }
 2334| return psf;
     |not affected ==> the lock is still locked. prev next
 2335|}
     |not affected ==> the lock is still locked. prev next
 2336|
 2337|static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_list *psf)
 2338|{
 2339| struct igmp_mcf_iter_state *state = ((struct igmp_mcf_iter_state *)(seq)->private);
 2340|
 2341| psf = psf->sf_next;
 2342| while (!psf) {
 2343|  __st_spin_unlock_bh_st__(&state->im->lock);
 2344|  state->im = state->im->next;
 2345|  while (!state->im) {
 2346|   state->dev = next_net_device_rcu(state->dev);
 2347|   if (!state->dev) {
 2348|    state->idev = ((void *)0);
 2349|    goto out;
 2350|   }
 2351|   state->idev = __in_dev_get_rcu(state->dev);
 2352|   if (!state->idev)
 2353|    continue;
 2354|   state->im = ({ typeof(*(state->idev->mc_list)) *_________p1 = (typeof(*(state->idev->mc_list))* )(*(volatile typeof((state->idev->mc_list)) *)&((state->idev->mc_list))); do { static bool __warned; if (debug_lockdep_rcu_enabled() && !__warned && !(rcu_read_lock_held() || (0))) { __warned = true; lockdep_rcu_dereference("net/ipv4/.tmp_igmp.o.armored.c", 2559); } } while (0); ; do { } while (0); ((typeof(*(state->idev->mc_list)) *)(_________p1)); });
 2355|  }
 2356|  if (!state->im)
 2357|   break;
 2358|  __st_spin_lock_bh_st__(&state->im->lock);
 2359|  psf = state->im->sources;
 2360| }
 2361|out:
 2362| return psf;
 2363|}
 2364|
 2365|static struct ip_sf_list *igmp_mcf_get_idx(struct seq_file *seq, loff_t pos)
 2366|{
 2367| struct ip_sf_list *psf = igmp_mcf_get_first(seq);
 2368| if (psf)
 2369|  while (pos && (psf = igmp_mcf_get_next(seq, psf)) != ((void *)0))
 2370|   --pos;
 2371| return pos ? ((void *)0) : psf;
 2372|}
 2373|
 2374|static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos)
 2375|
 2376|{
 2377| __st_rcu_read_lock_st__();
 2378| return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : ((void *)1);
 2379|}
 2380|
 2381|static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 2382|{
 2383| struct ip_sf_list *psf;
 2384| if (v == ((void *)1))
 2385|  psf = igmp_mcf_get_first(seq);
     |not affected ==> the lock is still locked. prev next
 2386| else
 2387|  psf = igmp_mcf_get_next(seq, v);
 2388| ++*pos;
     |not affected ==> the lock is still locked. prev next
 2389| return psf;
     |not affected ==> the lock is still locked. prev next
 2390|}
     |Leaving function in locked state.[& . * im_1 lock] prev
 2391|
 2392|static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
 2393|
 2394|{
 2395| struct igmp_mcf_iter_state *state = ((struct igmp_mcf_iter_state *)(seq)->private);
 2396| if (state->im != ((void *)0)) {
 2397|  __st_spin_unlock_bh_st__(&state->im->lock);
 2398|  state->im = ((void *)0);
 2399| }
 2400| state->idev = ((void *)0);
 2401| state->dev = ((void *)0);
 2402| __st_rcu_read_unlock_st__();
 2403|}
 2404|
 2405|static int igmp_mcf_seq_show(struct seq_file *seq, void *v)
 2406|{
 2407| struct ip_sf_list *psf = (struct ip_sf_list *)v;
 2408| struct igmp_mcf_iter_state *state = ((struct igmp_mcf_iter_state *)(seq)->private);
 2409|
 2410| if (v == ((void *)1)) {
 2411|  seq_printf(seq,
 2412|      "%3s %6s "
 2413|      "%10s %10s %6s %6s\n", "Idx",
 2414|      "Device", "MCA",
 2415|      "SRC", "INC", "EXC");
 2416| } else {
 2417|  seq_printf(seq,
 2418|      "%3d %6.6s 0x%08x "
 2419|      "0x%08x %6lu %6lu\n",
 2420|      state->dev->ifindex, state->dev->name,
 2421|      (__builtin_constant_p((__u32)(( __u32)(__be32)(state->im->multiaddr))) ? ((__u32)( (((__u32)(( __u32)(__be32)(state->im->multiaddr)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(state->im->multiaddr)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(state->im->multiaddr)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(state->im->multiaddr)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(state->im->multiaddr))),
 2422|      (__builtin_constant_p((__u32)(( __u32)(__be32)(psf->sf_inaddr))) ? ((__u32)( (((__u32)(( __u32)(__be32)(psf->sf_inaddr)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(psf->sf_inaddr)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(psf->sf_inaddr)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(psf->sf_inaddr)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(psf->sf_inaddr))),
 2423|      psf->sf_count[1],
 2424|      psf->sf_count[0]);
 2425| }
 2426| return 0;
 2427|}
 2428|
 2429|static const struct seq_operations igmp_mcf_seq_ops = {
 2430| .start = igmp_mcf_seq_start,
 2431| .next = igmp_mcf_seq_next,
 2432| .stop = igmp_mcf_seq_stop,
 2433| .show = igmp_mcf_seq_show,
 2434|};
 2435|
 2436|static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
 2437|{
 2438| return seq_open_net(inode, file, &igmp_mcf_seq_ops,
 2439|   sizeof(struct igmp_mcf_iter_state));
 2440|}
 2441|
 2442|static const struct file_operations igmp_mcf_seq_fops = {
 2443| .owner = ((struct module *)0),
 2444| .open = igmp_mcf_seq_open,
 2445| .read = seq_read,
 2446| .llseek = seq_lseek,
 2447| .release = seq_release_net,
 2448|};
 2449|
 2450|static int igmp_net_init(struct net *net)
 2451|{
 2452| struct proc_dir_entry *pde;
 2453|
 2454| pde = proc_net_fops_create(net, "igmp", (00400|00040|00004), &igmp_mc_seq_fops);
 2455| if (!pde)
 2456|  goto out_igmp;
 2457| pde = proc_net_fops_create(net, "mcfilter", (00400|00040|00004), &igmp_mcf_seq_fops);
 2458| if (!pde)
 2459|  goto out_mcfilter;
 2460| return 0;
 2461|
 2462|out_mcfilter:
 2463| proc_net_remove(net, "igmp");
 2464|out_igmp:
 2465| return -12;
 2466|}
 2467|
 2468|static void igmp_net_exit(struct net *net)
 2469|{
 2470| proc_net_remove(net, "mcfilter");
 2471| proc_net_remove(net, "igmp");
 2472|}
 2473|
 2474|static struct pernet_operations igmp_net_ops = {
 2475| .init = igmp_net_init,
 2476| .exit = igmp_net_exit,
 2477|};
 2478|
 2479|int igmp_mc_proc_init(void)
 2480|{
 2481| return register_pernet_subsys(&igmp_net_ops);
 2482|}