Lines Matching refs:amt
125 u32 hash = jhash(src, sizeof(*src), tunnel->amt->hash_seed); in amt_source_hash()
127 return reciprocal_scale(hash, tunnel->amt->hash_buckets); in amt_source_hash()
202 u32 hash = jhash(group, sizeof(*group), tunnel->amt->hash_seed); in amt_group_hash()
204 return reciprocal_scale(hash, tunnel->amt->hash_buckets); in amt_group_hash()
233 netdev_dbg(snode->gnode->amt->dev, in amt_destroy_source()
239 netdev_dbg(snode->gnode->amt->dev, in amt_destroy_source()
255 static void amt_del_group(struct amt_dev *amt, struct amt_group_node *gnode) in amt_del_group() argument
262 dev_put(amt->dev); in amt_del_group()
267 netdev_dbg(amt->dev, "Leave group %pI4\n", in amt_del_group()
271 netdev_dbg(amt->dev, "Leave group %pI6\n", in amt_del_group()
274 for (i = 0; i < amt->hash_buckets; i++) in amt_del_group()
295 struct amt_dev *amt = gnode->amt; in amt_source_work() local
304 amt_del_group(amt, gnode); in amt_source_work()
320 struct amt_dev *amt = tunnel->amt; in amt_act_src() local
325 msecs_to_jiffies(amt_gmi(amt))); in amt_act_src()
353 netdev_dbg(amt->dev, "Source %pI4 from %pI4 Acted %s\n", in amt_act_src()
359 netdev_dbg(amt->dev, "Source %pI6 from %pI6 Acted %s\n", in amt_act_src()
416 struct amt_dev *amt = gnode->amt; in amt_group_work() local
422 buckets = amt->hash_buckets; in amt_group_work()
445 amt_del_group(amt, gnode); in amt_group_work()
451 dev_put(amt->dev); in amt_group_work()
465 static struct amt_group_node *amt_add_group(struct amt_dev *amt, in amt_add_group() argument
475 if (tunnel->nr_groups >= amt->max_groups) in amt_add_group()
479 (sizeof(struct hlist_head) * amt->hash_buckets), in amt_add_group()
484 gnode->amt = amt; in amt_add_group()
492 for (i = 0; i < amt->hash_buckets; i++) in amt_add_group()
500 netdev_dbg(amt->dev, "Join group %pI4\n", in amt_add_group()
504 netdev_dbg(amt->dev, "Join group %pI6\n", in amt_add_group()
511 static struct sk_buff *amt_build_igmp_gq(struct amt_dev *amt) in amt_build_igmp_gq() argument
514 int hlen = LL_RESERVED_SPACE(amt->dev); in amt_build_igmp_gq()
515 int tlen = amt->dev->needed_tailroom; in amt_build_igmp_gq()
526 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_build_igmp_gq()
555 ether_addr_copy(eth->h_source, amt->dev->dev_addr); in amt_build_igmp_gq()
564 ihv3->qqic = amt->qi; in amt_build_igmp_gq()
568 ihv3->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv); in amt_build_igmp_gq()
582 static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status, in amt_update_gw_status() argument
585 if (validate && amt->status >= status) in amt_update_gw_status()
587 netdev_dbg(amt->dev, "Update GW status %s -> %s", in amt_update_gw_status()
588 status_str[amt->status], status_str[status]); in amt_update_gw_status()
589 WRITE_ONCE(amt->status, status); in amt_update_gw_status()
598 netdev_dbg(tunnel->amt->dev, in __amt_update_relay_status()
613 static void amt_send_discovery(struct amt_dev *amt) in amt_send_discovery() argument
627 sock = rcu_dereference(amt->sock); in amt_send_discovery()
631 if (!netif_running(amt->stream_dev) || !netif_running(amt->dev)) in amt_send_discovery()
634 rt = ip_route_output_ports(amt->net, &fl4, sock->sk, in amt_send_discovery()
635 amt->discovery_ip, amt->local_ip, in amt_send_discovery()
636 amt->gw_port, amt->relay_port, in amt_send_discovery()
638 amt->stream_dev->ifindex); in amt_send_discovery()
640 amt->dev->stats.tx_errors++; in amt_send_discovery()
644 hlen = LL_RESERVED_SPACE(amt->dev); in amt_send_discovery()
645 tlen = amt->dev->needed_tailroom; in amt_send_discovery()
647 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_send_discovery()
650 amt->dev->stats.tx_errors++; in amt_send_discovery()
664 amtd->nonce = amt->nonce; in amt_send_discovery()
668 udph->source = amt->gw_port; in amt_send_discovery()
669 udph->dest = amt->relay_port; in amt_send_discovery()
674 udph->check = csum_tcpudp_magic(amt->local_ip, amt->discovery_ip, in amt_send_discovery()
685 iph->daddr = amt->discovery_ip; in amt_send_discovery()
686 iph->saddr = amt->local_ip; in amt_send_discovery()
691 ip_select_ident(amt->net, skb, NULL); in amt_send_discovery()
693 err = ip_local_out(amt->net, sock->sk, skb); in amt_send_discovery()
695 amt->dev->stats.tx_errors++; in amt_send_discovery()
697 amt_update_gw_status(amt, AMT_STATUS_SENT_DISCOVERY, true); in amt_send_discovery()
702 static void amt_send_request(struct amt_dev *amt, bool v6) in amt_send_request() argument
716 sock = rcu_dereference(amt->sock); in amt_send_request()
720 if (!netif_running(amt->stream_dev) || !netif_running(amt->dev)) in amt_send_request()
723 rt = ip_route_output_ports(amt->net, &fl4, sock->sk, in amt_send_request()
724 amt->remote_ip, amt->local_ip, in amt_send_request()
725 amt->gw_port, amt->relay_port, in amt_send_request()
727 amt->stream_dev->ifindex); in amt_send_request()
729 amt->dev->stats.tx_errors++; in amt_send_request()
733 hlen = LL_RESERVED_SPACE(amt->dev); in amt_send_request()
734 tlen = amt->dev->needed_tailroom; in amt_send_request()
736 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_send_request()
739 amt->dev->stats.tx_errors++; in amt_send_request()
755 amtrh->nonce = amt->nonce; in amt_send_request()
759 udph->source = amt->gw_port; in amt_send_request()
760 udph->dest = amt->relay_port; in amt_send_request()
765 udph->check = csum_tcpudp_magic(amt->local_ip, amt->remote_ip, in amt_send_request()
776 iph->daddr = amt->remote_ip; in amt_send_request()
777 iph->saddr = amt->local_ip; in amt_send_request()
782 ip_select_ident(amt->net, skb, NULL); in amt_send_request()
784 err = ip_local_out(amt->net, sock->sk, skb); in amt_send_request()
786 amt->dev->stats.tx_errors++; in amt_send_request()
792 static void amt_send_igmp_gq(struct amt_dev *amt, in amt_send_igmp_gq() argument
797 skb = amt_build_igmp_gq(amt); in amt_send_igmp_gq()
806 static struct sk_buff *amt_build_mld_gq(struct amt_dev *amt) in amt_build_mld_gq() argument
810 int hlen = LL_RESERVED_SPACE(amt->dev); in amt_build_mld_gq()
811 int tlen = amt->dev->needed_tailroom; in amt_build_mld_gq()
820 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_build_mld_gq()
842 if (ipv6_dev_get_saddr(amt->net, amt->dev, &ip6h->daddr, 0, in amt_build_mld_gq()
844 amt->dev->stats.tx_errors++; in amt_build_mld_gq()
850 ether_addr_copy(eth->h_source, amt->dev->dev_addr); in amt_build_mld_gq()
863 mld2q->mld2q_qrv = amt->qrv; in amt_build_mld_gq()
865 mld2q->mld2q_qqic = amt->qi; in amt_build_mld_gq()
878 static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel) in amt_send_mld_gq() argument
882 skb = amt_build_mld_gq(amt); in amt_send_mld_gq()
890 static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel) in amt_send_mld_gq() argument
895 static bool amt_queue_event(struct amt_dev *amt, enum amt_event event, in amt_queue_event() argument
900 spin_lock_bh(&amt->lock); in amt_queue_event()
901 if (amt->nr_events >= AMT_MAX_EVENTS) { in amt_queue_event()
902 spin_unlock_bh(&amt->lock); in amt_queue_event()
906 index = (amt->event_idx + amt->nr_events) % AMT_MAX_EVENTS; in amt_queue_event()
907 amt->events[index].event = event; in amt_queue_event()
908 amt->events[index].skb = skb; in amt_queue_event()
909 amt->nr_events++; in amt_queue_event()
910 amt->event_idx %= AMT_MAX_EVENTS; in amt_queue_event()
911 queue_work(amt_wq, &amt->event_wq); in amt_queue_event()
912 spin_unlock_bh(&amt->lock); in amt_queue_event()
919 struct amt_dev *amt = container_of(to_delayed_work(work), in amt_secret_work() local
923 spin_lock_bh(&amt->lock); in amt_secret_work()
924 get_random_bytes(&amt->key, sizeof(siphash_key_t)); in amt_secret_work()
925 spin_unlock_bh(&amt->lock); in amt_secret_work()
926 mod_delayed_work(amt_wq, &amt->secret_wq, in amt_secret_work()
930 static void amt_event_send_discovery(struct amt_dev *amt) in amt_event_send_discovery() argument
932 if (amt->status > AMT_STATUS_SENT_DISCOVERY) in amt_event_send_discovery()
934 get_random_bytes(&amt->nonce, sizeof(__be32)); in amt_event_send_discovery()
936 amt_send_discovery(amt); in amt_event_send_discovery()
938 mod_delayed_work(amt_wq, &amt->discovery_wq, in amt_event_send_discovery()
944 struct amt_dev *amt = container_of(to_delayed_work(work), in amt_discovery_work() local
948 if (amt_queue_event(amt, AMT_EVENT_SEND_DISCOVERY, NULL)) in amt_discovery_work()
949 mod_delayed_work(amt_wq, &amt->discovery_wq, in amt_discovery_work()
953 static void amt_event_send_request(struct amt_dev *amt) in amt_event_send_request() argument
957 if (amt->status < AMT_STATUS_RECEIVED_ADVERTISEMENT) in amt_event_send_request()
960 if (amt->req_cnt > AMT_MAX_REQ_COUNT) { in amt_event_send_request()
961 netdev_dbg(amt->dev, "Gateway is not ready"); in amt_event_send_request()
962 amt->qi = AMT_INIT_REQ_TIMEOUT; in amt_event_send_request()
963 WRITE_ONCE(amt->ready4, false); in amt_event_send_request()
964 WRITE_ONCE(amt->ready6, false); in amt_event_send_request()
965 amt->remote_ip = 0; in amt_event_send_request()
966 amt_update_gw_status(amt, AMT_STATUS_INIT, false); in amt_event_send_request()
967 amt->req_cnt = 0; in amt_event_send_request()
968 amt->nonce = 0; in amt_event_send_request()
972 if (!amt->req_cnt) { in amt_event_send_request()
973 WRITE_ONCE(amt->ready4, false); in amt_event_send_request()
974 WRITE_ONCE(amt->ready6, false); in amt_event_send_request()
975 get_random_bytes(&amt->nonce, sizeof(__be32)); in amt_event_send_request()
978 amt_send_request(amt, false); in amt_event_send_request()
979 amt_send_request(amt, true); in amt_event_send_request()
980 amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true); in amt_event_send_request()
981 amt->req_cnt++; in amt_event_send_request()
983 exp = min_t(u32, (1 * (1 << amt->req_cnt)), AMT_MAX_REQ_TIMEOUT); in amt_event_send_request()
984 mod_delayed_work(amt_wq, &amt->req_wq, secs_to_jiffies(exp)); in amt_event_send_request()
989 struct amt_dev *amt = container_of(to_delayed_work(work), in amt_req_work() local
993 if (amt_queue_event(amt, AMT_EVENT_SEND_REQUEST, NULL)) in amt_req_work()
994 mod_delayed_work(amt_wq, &amt->req_wq, in amt_req_work()
998 static bool amt_send_membership_update(struct amt_dev *amt, in amt_send_membership_update() argument
1009 sock = rcu_dereference_bh(amt->sock); in amt_send_membership_update()
1013 err = skb_cow_head(skb, LL_RESERVED_SPACE(amt->dev) + sizeof(*amtmu) + in amt_send_membership_update()
1020 fl4.flowi4_oif = amt->stream_dev->ifindex; in amt_send_membership_update()
1021 fl4.daddr = amt->remote_ip; in amt_send_membership_update()
1022 fl4.saddr = amt->local_ip; in amt_send_membership_update()
1025 rt = ip_route_output_key(amt->net, &fl4); in amt_send_membership_update()
1027 netdev_dbg(amt->dev, "no route to %pI4\n", &amt->remote_ip); in amt_send_membership_update()
1035 amtmu->nonce = amt->nonce; in amt_send_membership_update()
1036 amtmu->response_mac = amt->mac; in amt_send_membership_update()
1048 amt->gw_port, in amt_send_membership_update()
1049 amt->relay_port, in amt_send_membership_update()
1053 amt_update_gw_status(amt, AMT_STATUS_SENT_UPDATE, true); in amt_send_membership_update()
1057 static void amt_send_multicast_data(struct amt_dev *amt, in amt_send_multicast_data() argument
1069 sock = rcu_dereference_bh(amt->sock); in amt_send_multicast_data()
1080 fl4.flowi4_oif = amt->stream_dev->ifindex; in amt_send_multicast_data()
1082 fl4.saddr = amt->local_ip; in amt_send_multicast_data()
1084 rt = ip_route_output_key(amt->net, &fl4); in amt_send_multicast_data()
1086 netdev_dbg(amt->dev, "no route to %pI4\n", &tunnel->ip4); in amt_send_multicast_data()
1106 amt->relay_port, in amt_send_multicast_data()
1113 static bool amt_send_membership_query(struct amt_dev *amt, in amt_send_membership_query() argument
1124 sock = rcu_dereference_bh(amt->sock); in amt_send_membership_query()
1128 err = skb_cow_head(skb, LL_RESERVED_SPACE(amt->dev) + sizeof(*amtmq) + in amt_send_membership_query()
1135 fl4.flowi4_oif = amt->stream_dev->ifindex; in amt_send_membership_query()
1137 fl4.saddr = amt->local_ip; in amt_send_membership_query()
1140 rt = ip_route_output_key(amt->net, &fl4); in amt_send_membership_query()
1142 netdev_dbg(amt->dev, "no route to %pI4\n", &tunnel->ip4); in amt_send_membership_query()
1165 amt->relay_port, in amt_send_membership_query()
1176 struct amt_dev *amt = netdev_priv(dev); in amt_dev_xmit() local
1250 if (amt->mode == AMT_MODE_GATEWAY) { in amt_dev_xmit()
1254 if ((!v6 && !READ_ONCE(amt->ready4)) || in amt_dev_xmit()
1255 (v6 && !READ_ONCE(amt->ready6))) in amt_dev_xmit()
1257 if (amt_send_membership_update(amt, skb, v6)) in amt_dev_xmit()
1260 } else if (amt->mode == AMT_MODE_RELAY) { in amt_dev_xmit()
1269 if (amt_send_membership_query(amt, skb, tunnel, v6)) in amt_dev_xmit()
1276 list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) { in amt_dev_xmit()
1293 amt_send_multicast_data(amt, skb, tunnel, v6); in amt_dev_xmit()
1326 struct amt_dev *amt = tunnel->amt; in amt_clear_groups() local
1333 for (i = 0; i < amt->hash_buckets; i++) in amt_clear_groups()
1335 amt_del_group(amt, gnode); in amt_clear_groups()
1345 struct amt_dev *amt = tunnel->amt; in amt_tunnel_expire() local
1347 spin_lock_bh(&amt->lock); in amt_tunnel_expire()
1350 amt->nr_tunnels--; in amt_tunnel_expire()
1353 spin_unlock_bh(&amt->lock); in amt_tunnel_expire()
1357 static void amt_cleanup_srcs(struct amt_dev *amt, in amt_cleanup_srcs() argument
1366 for (i = 0; i < amt->hash_buckets; i++) { in amt_cleanup_srcs()
1374 for (i = 0; i < amt->hash_buckets; i++) { in amt_cleanup_srcs()
1378 netdev_dbg(snode->gnode->amt->dev, in amt_cleanup_srcs()
1384 netdev_dbg(snode->gnode->amt->dev, in amt_cleanup_srcs()
1393 static void amt_add_srcs(struct amt_dev *amt, struct amt_tunnel_list *tunnel, in amt_add_srcs() argument
1419 if (tunnel->nr_sources >= amt->max_sources) in amt_add_srcs()
1439 netdev_dbg(snode->gnode->amt->dev, in amt_add_srcs()
1445 netdev_dbg(snode->gnode->amt->dev, in amt_add_srcs()
1481 struct amt_dev *amt = tunnel->amt; in amt_lookup_act_srcs() local
1524 for (i = 0; i < amt->hash_buckets; i++) { in amt_lookup_act_srcs()
1547 for (i = 0; i < amt->hash_buckets; i++) { in amt_lookup_act_srcs()
1592 netdev_dbg(amt->dev, "Invalid type\n"); in amt_lookup_act_srcs()
1597 static void amt_mcast_is_in_handler(struct amt_dev *amt, in amt_mcast_is_in_handler() argument
1650 static void amt_mcast_is_ex_handler(struct amt_dev *amt, in amt_mcast_is_ex_handler() argument
1679 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_is_ex_handler()
1680 dev_hold(amt->dev); in amt_mcast_is_ex_handler()
1708 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_is_ex_handler()
1709 dev_hold(amt->dev); in amt_mcast_is_ex_handler()
1714 static void amt_mcast_to_in_handler(struct amt_dev *amt, in amt_mcast_to_in_handler() argument
1775 static void amt_mcast_to_ex_handler(struct amt_dev *amt, in amt_mcast_to_ex_handler() argument
1805 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_to_ex_handler()
1806 dev_hold(amt->dev); in amt_mcast_to_ex_handler()
1835 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_to_ex_handler()
1836 dev_hold(amt->dev); in amt_mcast_to_ex_handler()
1841 static void amt_mcast_allow_handler(struct amt_dev *amt, in amt_mcast_allow_handler() argument
1886 static void amt_mcast_block_handler(struct amt_dev *amt, in amt_mcast_block_handler() argument
1942 static void amt_igmpv2_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmpv2_report_handler() argument
1957 gnode = amt_add_group(amt, tunnel, &group, &host, false); in amt_igmpv2_report_handler()
1961 msecs_to_jiffies(amt_gmi(amt)))) in amt_igmpv2_report_handler()
1962 dev_hold(amt->dev); in amt_igmpv2_report_handler()
1979 static void amt_igmpv2_leave_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmpv2_leave_handler() argument
1994 amt_del_group(amt, gnode); in amt_igmpv2_leave_handler()
1997 static void amt_igmpv3_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmpv3_report_handler() argument
2028 gnode = amt_add_group(amt, tunnel, &group, &host, in amt_igmpv3_report_handler()
2034 amt_add_srcs(amt, tunnel, gnode, grec, false); in amt_igmpv3_report_handler()
2037 amt_mcast_is_in_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2041 amt_mcast_is_ex_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2045 amt_mcast_to_in_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2049 amt_mcast_to_ex_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2053 amt_mcast_allow_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2057 amt_mcast_block_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2063 amt_cleanup_srcs(amt, tunnel, gnode); in amt_igmpv3_report_handler()
2068 static void amt_igmp_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmp_report_handler() argument
2075 amt_igmpv3_report_handler(amt, skb, tunnel); in amt_igmp_report_handler()
2078 amt_igmpv2_report_handler(amt, skb, tunnel); in amt_igmp_report_handler()
2081 amt_igmpv2_leave_handler(amt, skb, tunnel); in amt_igmp_report_handler()
2103 static void amt_mldv1_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mldv1_report_handler() argument
2116 gnode = amt_add_group(amt, tunnel, &group, &host, true); in amt_mldv1_report_handler()
2120 msecs_to_jiffies(amt_gmi(amt)))) in amt_mldv1_report_handler()
2121 dev_hold(amt->dev); in amt_mldv1_report_handler()
2140 static void amt_mldv1_leave_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mldv1_leave_handler() argument
2154 amt_del_group(amt, gnode); in amt_mldv1_leave_handler()
2159 static void amt_mldv2_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mldv2_report_handler() argument
2190 gnode = amt_add_group(amt, tunnel, &group, &host, in amt_mldv2_report_handler()
2196 amt_add_srcs(amt, tunnel, gnode, grec, true); in amt_mldv2_report_handler()
2199 amt_mcast_is_in_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2203 amt_mcast_is_ex_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2207 amt_mcast_to_in_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2211 amt_mcast_to_ex_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2215 amt_mcast_allow_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2219 amt_mcast_block_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2225 amt_cleanup_srcs(amt, tunnel, gnode); in amt_mldv2_report_handler()
2230 static void amt_mld_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mld_report_handler() argument
2237 amt_mldv1_report_handler(amt, skb, tunnel); in amt_mld_report_handler()
2240 amt_mldv2_report_handler(amt, skb, tunnel); in amt_mld_report_handler()
2243 amt_mldv1_leave_handler(amt, skb, tunnel); in amt_mld_report_handler()
2251 static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_advertisement_handler() argument
2271 if (amt->status != AMT_STATUS_SENT_DISCOVERY || in amt_advertisement_handler()
2272 amt->nonce != amta->nonce) in amt_advertisement_handler()
2275 amt->remote_ip = amta->ip4; in amt_advertisement_handler()
2276 netdev_dbg(amt->dev, "advertised remote ip = %pI4\n", &amt->remote_ip); in amt_advertisement_handler()
2277 mod_delayed_work(amt_wq, &amt->req_wq, 0); in amt_advertisement_handler()
2279 amt_update_gw_status(amt, AMT_STATUS_RECEIVED_ADVERTISEMENT, true); in amt_advertisement_handler()
2283 static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_multicast_data_handler() argument
2290 if (READ_ONCE(amt->status) != AMT_STATUS_SENT_UPDATE) in amt_multicast_data_handler()
2341 err = gro_cells_receive(&amt->gro_cells, skb); in amt_multicast_data_handler()
2343 dev_sw_netstats_rx_add(amt->dev, len); in amt_multicast_data_handler()
2345 amt->dev->stats.rx_dropped++; in amt_multicast_data_handler()
2350 static bool amt_membership_query_handler(struct amt_dev *amt, in amt_membership_query_handler() argument
2367 if (amtmq->nonce != amt->nonce) in amt_membership_query_handler()
2384 if (READ_ONCE(amt->ready4)) in amt_membership_query_handler()
2397 WRITE_ONCE(amt->ready4, true); in amt_membership_query_handler()
2398 amt->mac = amtmq->response_mac; in amt_membership_query_handler()
2399 amt->req_cnt = 0; in amt_membership_query_handler()
2400 amt->qi = ihv3->qqic; in amt_membership_query_handler()
2409 if (READ_ONCE(amt->ready6)) in amt_membership_query_handler()
2423 WRITE_ONCE(amt->ready6, true); in amt_membership_query_handler()
2424 amt->mac = amtmq->response_mac; in amt_membership_query_handler()
2425 amt->req_cnt = 0; in amt_membership_query_handler()
2426 amt->qi = mld2q->mld2q_qqic; in amt_membership_query_handler()
2441 amt_update_gw_status(amt, AMT_STATUS_RECEIVED_QUERY, true); in amt_membership_query_handler()
2442 dev_sw_netstats_rx_add(amt->dev, len); in amt_membership_query_handler()
2444 amt->dev->stats.rx_dropped++; in amt_membership_query_handler()
2451 static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_update_handler() argument
2474 list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) { in amt_update_handler()
2479 msecs_to_jiffies(amt_gmi(amt)) in amt_update_handler()
2483 netdev_dbg(amt->dev, "Invalid MAC\n"); in amt_update_handler()
2498 netdev_dbg(amt->dev, "Invalid IGMP\n"); in amt_update_handler()
2503 amt_igmp_report_handler(amt, skb, tunnel); in amt_update_handler()
2517 netdev_dbg(amt->dev, "Invalid MLD\n"); in amt_update_handler()
2522 amt_mld_report_handler(amt, skb, tunnel); in amt_update_handler()
2533 netdev_dbg(amt->dev, "Unsupported Protocol\n"); in amt_update_handler()
2544 dev_sw_netstats_rx_add(amt->dev, len); in amt_update_handler()
2546 amt->dev->stats.rx_dropped++; in amt_update_handler()
2552 static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce, in amt_send_advertisement() argument
2567 sock = rcu_dereference(amt->sock); in amt_send_advertisement()
2571 if (!netif_running(amt->stream_dev) || !netif_running(amt->dev)) in amt_send_advertisement()
2574 rt = ip_route_output_ports(amt->net, &fl4, sock->sk, in amt_send_advertisement()
2575 daddr, amt->local_ip, in amt_send_advertisement()
2576 dport, amt->relay_port, in amt_send_advertisement()
2578 amt->stream_dev->ifindex); in amt_send_advertisement()
2580 amt->dev->stats.tx_errors++; in amt_send_advertisement()
2584 hlen = LL_RESERVED_SPACE(amt->dev); in amt_send_advertisement()
2585 tlen = amt->dev->needed_tailroom; in amt_send_advertisement()
2587 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_send_advertisement()
2590 amt->dev->stats.tx_errors++; in amt_send_advertisement()
2605 amta->ip4 = amt->local_ip; in amt_send_advertisement()
2609 udph->source = amt->relay_port; in amt_send_advertisement()
2615 udph->check = csum_tcpudp_magic(amt->local_ip, daddr, in amt_send_advertisement()
2627 iph->saddr = amt->local_ip; in amt_send_advertisement()
2632 ip_select_ident(amt->net, skb, NULL); in amt_send_advertisement()
2634 err = ip_local_out(amt->net, sock->sk, skb); in amt_send_advertisement()
2636 amt->dev->stats.tx_errors++; in amt_send_advertisement()
2642 static bool amt_discovery_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_discovery_handler() argument
2658 amt_send_advertisement(amt, amtd->nonce, iph->saddr, udph->source); in amt_discovery_handler()
2663 static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_request_handler() argument
2683 list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) in amt_request_handler()
2687 spin_lock_bh(&amt->lock); in amt_request_handler()
2688 if (amt->nr_tunnels >= amt->max_tunnels) { in amt_request_handler()
2689 spin_unlock_bh(&amt->lock); in amt_request_handler()
2695 (sizeof(struct hlist_head) * amt->hash_buckets), in amt_request_handler()
2698 spin_unlock_bh(&amt->lock); in amt_request_handler()
2706 tunnel->amt = amt; in amt_request_handler()
2708 for (i = 0; i < amt->hash_buckets; i++) in amt_request_handler()
2713 list_add_tail_rcu(&tunnel->list, &amt->tunnel_list); in amt_request_handler()
2714 tunnel->key = amt->key; in amt_request_handler()
2716 amt->nr_tunnels++; in amt_request_handler()
2718 msecs_to_jiffies(amt_gmi(amt))); in amt_request_handler()
2719 spin_unlock_bh(&amt->lock); in amt_request_handler()
2729 if (!netif_running(amt->dev) || !netif_running(amt->stream_dev)) in amt_request_handler()
2733 amt_send_igmp_gq(amt, tunnel); in amt_request_handler()
2735 amt_send_mld_gq(amt, tunnel); in amt_request_handler()
2740 static void amt_gw_rcv(struct amt_dev *amt, struct sk_buff *skb) in amt_gw_rcv() argument
2748 if (amt->mode == AMT_MODE_GATEWAY) { in amt_gw_rcv()
2751 err = amt_advertisement_handler(amt, skb); in amt_gw_rcv()
2754 err = amt_membership_query_handler(amt, skb); in amt_gw_rcv()
2759 netdev_dbg(amt->dev, "Invalid type of Gateway\n"); in amt_gw_rcv()
2765 amt->dev->stats.rx_dropped++; in amt_gw_rcv()
2774 struct amt_dev *amt; in amt_rcv() local
2780 amt = rcu_dereference_sk_user_data(sk); in amt_rcv()
2781 if (!amt) { in amt_rcv()
2787 skb->dev = amt->dev; in amt_rcv()
2795 if (amt->mode == AMT_MODE_GATEWAY) { in amt_rcv()
2798 if (iph->saddr != amt->discovery_ip) { in amt_rcv()
2799 netdev_dbg(amt->dev, "Invalid Relay IP\n"); in amt_rcv()
2803 if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) { in amt_rcv()
2804 netdev_dbg(amt->dev, "AMT Event queue full\n"); in amt_rcv()
2810 if (iph->saddr != amt->remote_ip) { in amt_rcv()
2811 netdev_dbg(amt->dev, "Invalid Relay IP\n"); in amt_rcv()
2815 err = amt_multicast_data_handler(amt, skb); in amt_rcv()
2821 if (iph->saddr != amt->remote_ip) { in amt_rcv()
2822 netdev_dbg(amt->dev, "Invalid Relay IP\n"); in amt_rcv()
2826 if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) { in amt_rcv()
2827 netdev_dbg(amt->dev, "AMT Event queue full\n"); in amt_rcv()
2834 netdev_dbg(amt->dev, "Invalid type of Gateway\n"); in amt_rcv()
2840 err = amt_discovery_handler(amt, skb); in amt_rcv()
2843 err = amt_request_handler(amt, skb); in amt_rcv()
2846 err = amt_update_handler(amt, skb); in amt_rcv()
2853 netdev_dbg(amt->dev, "Invalid type of relay\n"); in amt_rcv()
2859 amt->dev->stats.rx_dropped++; in amt_rcv()
2871 struct amt_dev *amt = container_of(work, struct amt_dev, event_wq); in amt_event_work() local
2877 spin_lock_bh(&amt->lock); in amt_event_work()
2878 if (amt->nr_events == 0) { in amt_event_work()
2879 spin_unlock_bh(&amt->lock); in amt_event_work()
2882 event = amt->events[amt->event_idx].event; in amt_event_work()
2883 skb = amt->events[amt->event_idx].skb; in amt_event_work()
2884 amt->events[amt->event_idx].event = AMT_EVENT_NONE; in amt_event_work()
2885 amt->events[amt->event_idx].skb = NULL; in amt_event_work()
2886 amt->nr_events--; in amt_event_work()
2887 amt->event_idx++; in amt_event_work()
2888 amt->event_idx %= AMT_MAX_EVENTS; in amt_event_work()
2889 spin_unlock_bh(&amt->lock); in amt_event_work()
2893 amt_gw_rcv(amt, skb); in amt_event_work()
2896 amt_event_send_discovery(amt); in amt_event_work()
2899 amt_event_send_request(amt); in amt_event_work()
2910 struct amt_dev *amt; in amt_err_lookup() local
2914 amt = rcu_dereference_sk_user_data(sk); in amt_err_lookup()
2915 if (!amt) in amt_err_lookup()
2918 if (amt->mode != AMT_MODE_GATEWAY) in amt_err_lookup()
2925 netdev_dbg(amt->dev, "Received IGMP Unreachable of %s\n", in amt_err_lookup()
2932 if (READ_ONCE(amt->status) >= AMT_STATUS_RECEIVED_ADVERTISEMENT) in amt_err_lookup()
2933 mod_delayed_work(amt_wq, &amt->req_wq, 0); in amt_err_lookup()
2943 amt->dev->stats.rx_dropped++; in amt_err_lookup()
2966 static int amt_socket_create(struct amt_dev *amt) in amt_socket_create() argument
2971 sock = amt_create_sock(amt->net, amt->relay_port); in amt_socket_create()
2977 tunnel_cfg.sk_user_data = amt; in amt_socket_create()
2982 setup_udp_tunnel_sock(amt->net, sock, &tunnel_cfg); in amt_socket_create()
2984 rcu_assign_pointer(amt->sock, sock); in amt_socket_create()
2990 struct amt_dev *amt = netdev_priv(dev); in amt_dev_open() local
2993 amt->ready4 = false; in amt_dev_open()
2994 amt->ready6 = false; in amt_dev_open()
2995 amt->event_idx = 0; in amt_dev_open()
2996 amt->nr_events = 0; in amt_dev_open()
2998 err = amt_socket_create(amt); in amt_dev_open()
3002 amt->req_cnt = 0; in amt_dev_open()
3003 amt->remote_ip = 0; in amt_dev_open()
3004 amt->nonce = 0; in amt_dev_open()
3005 get_random_bytes(&amt->key, sizeof(siphash_key_t)); in amt_dev_open()
3007 amt->status = AMT_STATUS_INIT; in amt_dev_open()
3008 if (amt->mode == AMT_MODE_GATEWAY) { in amt_dev_open()
3009 mod_delayed_work(amt_wq, &amt->discovery_wq, 0); in amt_dev_open()
3010 mod_delayed_work(amt_wq, &amt->req_wq, 0); in amt_dev_open()
3011 } else if (amt->mode == AMT_MODE_RELAY) { in amt_dev_open()
3012 mod_delayed_work(amt_wq, &amt->secret_wq, in amt_dev_open()
3020 struct amt_dev *amt = netdev_priv(dev); in amt_dev_stop() local
3026 cancel_delayed_work_sync(&amt->req_wq); in amt_dev_stop()
3027 cancel_delayed_work_sync(&amt->discovery_wq); in amt_dev_stop()
3028 cancel_delayed_work_sync(&amt->secret_wq); in amt_dev_stop()
3031 sock = rtnl_dereference(amt->sock); in amt_dev_stop()
3032 RCU_INIT_POINTER(amt->sock, NULL); in amt_dev_stop()
3037 cancel_work_sync(&amt->event_wq); in amt_dev_stop()
3039 skb = amt->events[i].skb; in amt_dev_stop()
3041 amt->events[i].event = AMT_EVENT_NONE; in amt_dev_stop()
3042 amt->events[i].skb = NULL; in amt_dev_stop()
3045 amt->ready4 = false; in amt_dev_stop()
3046 amt->ready6 = false; in amt_dev_stop()
3047 amt->req_cnt = 0; in amt_dev_stop()
3048 amt->remote_ip = 0; in amt_dev_stop()
3050 list_for_each_entry_safe(tunnel, tmp, &amt->tunnel_list, list) { in amt_dev_stop()
3052 amt->nr_tunnels--; in amt_dev_stop()
3067 struct amt_dev *amt = netdev_priv(dev); in amt_dev_init() local
3070 amt->dev = dev; in amt_dev_init()
3072 err = gro_cells_init(&amt->gro_cells, dev); in amt_dev_init()
3081 struct amt_dev *amt = netdev_priv(dev); in amt_dev_uninit() local
3083 gro_cells_destroy(&amt->gro_cells); in amt_dev_uninit()
3174 struct amt_dev *amt = netdev_priv(dev); in amt_newlink() local
3179 amt->net = link_net; in amt_newlink()
3180 amt->mode = nla_get_u32(data[IFLA_AMT_MODE]); in amt_newlink()
3184 amt->max_tunnels = nla_get_u32(data[IFLA_AMT_MAX_TUNNELS]); in amt_newlink()
3186 amt->max_tunnels = AMT_MAX_TUNNELS; in amt_newlink()
3188 spin_lock_init(&amt->lock); in amt_newlink()
3189 amt->max_groups = AMT_MAX_GROUP; in amt_newlink()
3190 amt->max_sources = AMT_MAX_SOURCE; in amt_newlink()
3191 amt->hash_buckets = AMT_HSIZE; in amt_newlink()
3192 amt->nr_tunnels = 0; in amt_newlink()
3193 get_random_bytes(&amt->hash_seed, sizeof(amt->hash_seed)); in amt_newlink()
3194 amt->stream_dev = dev_get_by_index(link_net, in amt_newlink()
3196 if (!amt->stream_dev) { in amt_newlink()
3202 if (amt->stream_dev->type != ARPHRD_ETHER) { in amt_newlink()
3208 amt->local_ip = nla_get_in_addr(data[IFLA_AMT_LOCAL_IP]); in amt_newlink()
3209 if (ipv4_is_loopback(amt->local_ip) || in amt_newlink()
3210 ipv4_is_zeronet(amt->local_ip) || in amt_newlink()
3211 ipv4_is_multicast(amt->local_ip)) { in amt_newlink()
3217 amt->relay_port = nla_get_be16_default(data[IFLA_AMT_RELAY_PORT], in amt_newlink()
3220 amt->gw_port = nla_get_be16_default(data[IFLA_AMT_GATEWAY_PORT], in amt_newlink()
3223 if (!amt->relay_port) { in amt_newlink()
3228 if (amt->mode == AMT_MODE_RELAY) { in amt_newlink()
3229 amt->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv); in amt_newlink()
3230 amt->qri = 10; in amt_newlink()
3231 dev->needed_headroom = amt->stream_dev->needed_headroom + in amt_newlink()
3233 dev->mtu = amt->stream_dev->mtu - AMT_RELAY_HLEN; in amt_newlink()
3242 if (!amt->gw_port) { in amt_newlink()
3247 amt->remote_ip = 0; in amt_newlink()
3248 amt->discovery_ip = nla_get_in_addr(data[IFLA_AMT_DISCOVERY_IP]); in amt_newlink()
3249 if (ipv4_is_loopback(amt->discovery_ip) || in amt_newlink()
3250 ipv4_is_zeronet(amt->discovery_ip) || in amt_newlink()
3251 ipv4_is_multicast(amt->discovery_ip)) { in amt_newlink()
3257 dev->needed_headroom = amt->stream_dev->needed_headroom + in amt_newlink()
3259 dev->mtu = amt->stream_dev->mtu - AMT_GW_HLEN; in amt_newlink()
3263 amt->qi = AMT_INIT_QUERY_INTERVAL; in amt_newlink()
3271 err = netdev_upper_dev_link(amt->stream_dev, dev, extack); in amt_newlink()
3277 INIT_DELAYED_WORK(&amt->discovery_wq, amt_discovery_work); in amt_newlink()
3278 INIT_DELAYED_WORK(&amt->req_wq, amt_req_work); in amt_newlink()
3279 INIT_DELAYED_WORK(&amt->secret_wq, amt_secret_work); in amt_newlink()
3280 INIT_WORK(&amt->event_wq, amt_event_work); in amt_newlink()
3281 INIT_LIST_HEAD(&amt->tunnel_list); in amt_newlink()
3284 dev_put(amt->stream_dev); in amt_newlink()
3290 struct amt_dev *amt = netdev_priv(dev); in amt_dellink() local
3293 netdev_upper_dev_unlink(amt->stream_dev, dev); in amt_dellink()
3294 dev_put(amt->stream_dev); in amt_dellink()
3311 struct amt_dev *amt = netdev_priv(dev); in amt_fill_info() local
3313 if (nla_put_u32(skb, IFLA_AMT_MODE, amt->mode)) in amt_fill_info()
3315 if (nla_put_be16(skb, IFLA_AMT_RELAY_PORT, amt->relay_port)) in amt_fill_info()
3317 if (nla_put_be16(skb, IFLA_AMT_GATEWAY_PORT, amt->gw_port)) in amt_fill_info()
3319 if (nla_put_u32(skb, IFLA_AMT_LINK, amt->stream_dev->ifindex)) in amt_fill_info()
3321 if (nla_put_in_addr(skb, IFLA_AMT_LOCAL_IP, amt->local_ip)) in amt_fill_info()
3323 if (nla_put_in_addr(skb, IFLA_AMT_DISCOVERY_IP, amt->discovery_ip)) in amt_fill_info()
3325 if (amt->remote_ip) in amt_fill_info()
3326 if (nla_put_in_addr(skb, IFLA_AMT_REMOTE_IP, amt->remote_ip)) in amt_fill_info()
3328 if (nla_put_u32(skb, IFLA_AMT_MAX_TUNNELS, amt->max_tunnels)) in amt_fill_info()
3353 struct amt_dev *amt; in amt_lookup_upper_dev() local
3357 amt = netdev_priv(upper_dev); in amt_lookup_upper_dev()
3358 if (amt->stream_dev == dev) in amt_lookup_upper_dev()
3371 struct amt_dev *amt; in amt_device_event() local
3378 amt = netdev_priv(upper_dev); in amt_device_event()
3382 amt_dellink(amt->dev, &list); in amt_device_event()
3386 if (amt->mode == AMT_MODE_RELAY) in amt_device_event()
3391 dev_set_mtu(amt->dev, new_mtu); in amt_device_event()