Lines Matching refs:amt

123 	u32 hash = jhash(src, sizeof(*src), tunnel->amt->hash_seed);  in amt_source_hash()
125 return reciprocal_scale(hash, tunnel->amt->hash_buckets); in amt_source_hash()
200 u32 hash = jhash(group, sizeof(*group), tunnel->amt->hash_seed); in amt_group_hash()
202 return reciprocal_scale(hash, tunnel->amt->hash_buckets); in amt_group_hash()
231 netdev_dbg(snode->gnode->amt->dev, in amt_destroy_source()
237 netdev_dbg(snode->gnode->amt->dev, in amt_destroy_source()
253 static void amt_del_group(struct amt_dev *amt, struct amt_group_node *gnode) in amt_del_group() argument
260 dev_put(amt->dev); in amt_del_group()
265 netdev_dbg(amt->dev, "Leave group %pI4\n", in amt_del_group()
269 netdev_dbg(amt->dev, "Leave group %pI6\n", in amt_del_group()
272 for (i = 0; i < amt->hash_buckets; i++) in amt_del_group()
293 struct amt_dev *amt = gnode->amt; in amt_source_work() local
302 amt_del_group(amt, gnode); in amt_source_work()
318 struct amt_dev *amt = tunnel->amt; in amt_act_src() local
323 msecs_to_jiffies(amt_gmi(amt))); in amt_act_src()
351 netdev_dbg(amt->dev, "Source %pI4 from %pI4 Acted %s\n", in amt_act_src()
357 netdev_dbg(amt->dev, "Source %pI6 from %pI6 Acted %s\n", in amt_act_src()
414 struct amt_dev *amt = gnode->amt; in amt_group_work() local
420 buckets = amt->hash_buckets; in amt_group_work()
443 amt_del_group(amt, gnode); in amt_group_work()
449 dev_put(amt->dev); in amt_group_work()
463 static struct amt_group_node *amt_add_group(struct amt_dev *amt, in amt_add_group() argument
473 if (tunnel->nr_groups >= amt->max_groups) in amt_add_group()
477 (sizeof(struct hlist_head) * amt->hash_buckets), in amt_add_group()
482 gnode->amt = amt; in amt_add_group()
490 for (i = 0; i < amt->hash_buckets; i++) in amt_add_group()
498 netdev_dbg(amt->dev, "Join group %pI4\n", in amt_add_group()
502 netdev_dbg(amt->dev, "Join group %pI6\n", in amt_add_group()
509 static struct sk_buff *amt_build_igmp_gq(struct amt_dev *amt) in amt_build_igmp_gq() argument
512 int hlen = LL_RESERVED_SPACE(amt->dev); in amt_build_igmp_gq()
513 int tlen = amt->dev->needed_tailroom; in amt_build_igmp_gq()
524 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_build_igmp_gq()
553 ether_addr_copy(eth->h_source, amt->dev->dev_addr); in amt_build_igmp_gq()
562 ihv3->qqic = amt->qi; in amt_build_igmp_gq()
566 ihv3->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv); in amt_build_igmp_gq()
580 static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status, in amt_update_gw_status() argument
583 if (validate && amt->status >= status) in amt_update_gw_status()
585 netdev_dbg(amt->dev, "Update GW status %s -> %s", in amt_update_gw_status()
586 status_str[amt->status], status_str[status]); in amt_update_gw_status()
587 WRITE_ONCE(amt->status, status); in amt_update_gw_status()
596 netdev_dbg(tunnel->amt->dev, in __amt_update_relay_status()
611 static void amt_send_discovery(struct amt_dev *amt) in amt_send_discovery() argument
625 sock = rcu_dereference(amt->sock); in amt_send_discovery()
629 if (!netif_running(amt->stream_dev) || !netif_running(amt->dev)) in amt_send_discovery()
632 rt = ip_route_output_ports(amt->net, &fl4, sock->sk, in amt_send_discovery()
633 amt->discovery_ip, amt->local_ip, in amt_send_discovery()
634 amt->gw_port, amt->relay_port, in amt_send_discovery()
636 amt->stream_dev->ifindex); in amt_send_discovery()
638 amt->dev->stats.tx_errors++; in amt_send_discovery()
642 hlen = LL_RESERVED_SPACE(amt->dev); in amt_send_discovery()
643 tlen = amt->dev->needed_tailroom; in amt_send_discovery()
645 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_send_discovery()
648 amt->dev->stats.tx_errors++; in amt_send_discovery()
662 amtd->nonce = amt->nonce; in amt_send_discovery()
666 udph->source = amt->gw_port; in amt_send_discovery()
667 udph->dest = amt->relay_port; in amt_send_discovery()
672 udph->check = csum_tcpudp_magic(amt->local_ip, amt->discovery_ip, in amt_send_discovery()
683 iph->daddr = amt->discovery_ip; in amt_send_discovery()
684 iph->saddr = amt->local_ip; in amt_send_discovery()
689 ip_select_ident(amt->net, skb, NULL); in amt_send_discovery()
691 err = ip_local_out(amt->net, sock->sk, skb); in amt_send_discovery()
693 amt->dev->stats.tx_errors++; in amt_send_discovery()
695 amt_update_gw_status(amt, AMT_STATUS_SENT_DISCOVERY, true); in amt_send_discovery()
700 static void amt_send_request(struct amt_dev *amt, bool v6) in amt_send_request() argument
714 sock = rcu_dereference(amt->sock); in amt_send_request()
718 if (!netif_running(amt->stream_dev) || !netif_running(amt->dev)) in amt_send_request()
721 rt = ip_route_output_ports(amt->net, &fl4, sock->sk, in amt_send_request()
722 amt->remote_ip, amt->local_ip, in amt_send_request()
723 amt->gw_port, amt->relay_port, in amt_send_request()
725 amt->stream_dev->ifindex); in amt_send_request()
727 amt->dev->stats.tx_errors++; in amt_send_request()
731 hlen = LL_RESERVED_SPACE(amt->dev); in amt_send_request()
732 tlen = amt->dev->needed_tailroom; in amt_send_request()
734 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_send_request()
737 amt->dev->stats.tx_errors++; in amt_send_request()
753 amtrh->nonce = amt->nonce; in amt_send_request()
757 udph->source = amt->gw_port; in amt_send_request()
758 udph->dest = amt->relay_port; in amt_send_request()
763 udph->check = csum_tcpudp_magic(amt->local_ip, amt->remote_ip, in amt_send_request()
774 iph->daddr = amt->remote_ip; in amt_send_request()
775 iph->saddr = amt->local_ip; in amt_send_request()
780 ip_select_ident(amt->net, skb, NULL); in amt_send_request()
782 err = ip_local_out(amt->net, sock->sk, skb); in amt_send_request()
784 amt->dev->stats.tx_errors++; in amt_send_request()
790 static void amt_send_igmp_gq(struct amt_dev *amt, in amt_send_igmp_gq() argument
795 skb = amt_build_igmp_gq(amt); in amt_send_igmp_gq()
804 static struct sk_buff *amt_build_mld_gq(struct amt_dev *amt) in amt_build_mld_gq() argument
808 int hlen = LL_RESERVED_SPACE(amt->dev); in amt_build_mld_gq()
809 int tlen = amt->dev->needed_tailroom; in amt_build_mld_gq()
818 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_build_mld_gq()
840 if (ipv6_dev_get_saddr(amt->net, amt->dev, &ip6h->daddr, 0, in amt_build_mld_gq()
842 amt->dev->stats.tx_errors++; in amt_build_mld_gq()
848 ether_addr_copy(eth->h_source, amt->dev->dev_addr); in amt_build_mld_gq()
861 mld2q->mld2q_qrv = amt->qrv; in amt_build_mld_gq()
863 mld2q->mld2q_qqic = amt->qi; in amt_build_mld_gq()
876 static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel) in amt_send_mld_gq() argument
880 skb = amt_build_mld_gq(amt); in amt_send_mld_gq()
888 static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel) in amt_send_mld_gq() argument
893 static bool amt_queue_event(struct amt_dev *amt, enum amt_event event, in amt_queue_event() argument
898 spin_lock_bh(&amt->lock); in amt_queue_event()
899 if (amt->nr_events >= AMT_MAX_EVENTS) { in amt_queue_event()
900 spin_unlock_bh(&amt->lock); in amt_queue_event()
904 index = (amt->event_idx + amt->nr_events) % AMT_MAX_EVENTS; in amt_queue_event()
905 amt->events[index].event = event; in amt_queue_event()
906 amt->events[index].skb = skb; in amt_queue_event()
907 amt->nr_events++; in amt_queue_event()
908 amt->event_idx %= AMT_MAX_EVENTS; in amt_queue_event()
909 queue_work(amt_wq, &amt->event_wq); in amt_queue_event()
910 spin_unlock_bh(&amt->lock); in amt_queue_event()
917 struct amt_dev *amt = container_of(to_delayed_work(work), in amt_secret_work() local
921 spin_lock_bh(&amt->lock); in amt_secret_work()
922 get_random_bytes(&amt->key, sizeof(siphash_key_t)); in amt_secret_work()
923 spin_unlock_bh(&amt->lock); in amt_secret_work()
924 mod_delayed_work(amt_wq, &amt->secret_wq, in amt_secret_work()
928 static void amt_event_send_discovery(struct amt_dev *amt) in amt_event_send_discovery() argument
930 if (amt->status > AMT_STATUS_SENT_DISCOVERY) in amt_event_send_discovery()
932 get_random_bytes(&amt->nonce, sizeof(__be32)); in amt_event_send_discovery()
934 amt_send_discovery(amt); in amt_event_send_discovery()
936 mod_delayed_work(amt_wq, &amt->discovery_wq, in amt_event_send_discovery()
942 struct amt_dev *amt = container_of(to_delayed_work(work), in amt_discovery_work() local
946 if (amt_queue_event(amt, AMT_EVENT_SEND_DISCOVERY, NULL)) in amt_discovery_work()
947 mod_delayed_work(amt_wq, &amt->discovery_wq, in amt_discovery_work()
951 static void amt_event_send_request(struct amt_dev *amt) in amt_event_send_request() argument
955 if (amt->status < AMT_STATUS_RECEIVED_ADVERTISEMENT) in amt_event_send_request()
958 if (amt->req_cnt > AMT_MAX_REQ_COUNT) { in amt_event_send_request()
959 netdev_dbg(amt->dev, "Gateway is not ready"); in amt_event_send_request()
960 amt->qi = AMT_INIT_REQ_TIMEOUT; in amt_event_send_request()
961 WRITE_ONCE(amt->ready4, false); in amt_event_send_request()
962 WRITE_ONCE(amt->ready6, false); in amt_event_send_request()
963 amt->remote_ip = 0; in amt_event_send_request()
964 amt_update_gw_status(amt, AMT_STATUS_INIT, false); in amt_event_send_request()
965 amt->req_cnt = 0; in amt_event_send_request()
966 amt->nonce = 0; in amt_event_send_request()
970 if (!amt->req_cnt) { in amt_event_send_request()
971 WRITE_ONCE(amt->ready4, false); in amt_event_send_request()
972 WRITE_ONCE(amt->ready6, false); in amt_event_send_request()
973 get_random_bytes(&amt->nonce, sizeof(__be32)); in amt_event_send_request()
976 amt_send_request(amt, false); in amt_event_send_request()
977 amt_send_request(amt, true); in amt_event_send_request()
978 amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true); in amt_event_send_request()
979 amt->req_cnt++; in amt_event_send_request()
981 exp = min_t(u32, (1 * (1 << amt->req_cnt)), AMT_MAX_REQ_TIMEOUT); in amt_event_send_request()
982 mod_delayed_work(amt_wq, &amt->req_wq, msecs_to_jiffies(exp * 1000)); in amt_event_send_request()
987 struct amt_dev *amt = container_of(to_delayed_work(work), in amt_req_work() local
991 if (amt_queue_event(amt, AMT_EVENT_SEND_REQUEST, NULL)) in amt_req_work()
992 mod_delayed_work(amt_wq, &amt->req_wq, in amt_req_work()
996 static bool amt_send_membership_update(struct amt_dev *amt, in amt_send_membership_update() argument
1007 sock = rcu_dereference_bh(amt->sock); in amt_send_membership_update()
1011 err = skb_cow_head(skb, LL_RESERVED_SPACE(amt->dev) + sizeof(*amtmu) + in amt_send_membership_update()
1018 fl4.flowi4_oif = amt->stream_dev->ifindex; in amt_send_membership_update()
1019 fl4.daddr = amt->remote_ip; in amt_send_membership_update()
1020 fl4.saddr = amt->local_ip; in amt_send_membership_update()
1023 rt = ip_route_output_key(amt->net, &fl4); in amt_send_membership_update()
1025 netdev_dbg(amt->dev, "no route to %pI4\n", &amt->remote_ip); in amt_send_membership_update()
1033 amtmu->nonce = amt->nonce; in amt_send_membership_update()
1034 amtmu->response_mac = amt->mac; in amt_send_membership_update()
1046 amt->gw_port, in amt_send_membership_update()
1047 amt->relay_port, in amt_send_membership_update()
1050 amt_update_gw_status(amt, AMT_STATUS_SENT_UPDATE, true); in amt_send_membership_update()
1054 static void amt_send_multicast_data(struct amt_dev *amt, in amt_send_multicast_data() argument
1066 sock = rcu_dereference_bh(amt->sock); in amt_send_multicast_data()
1077 fl4.flowi4_oif = amt->stream_dev->ifindex; in amt_send_multicast_data()
1079 fl4.saddr = amt->local_ip; in amt_send_multicast_data()
1081 rt = ip_route_output_key(amt->net, &fl4); in amt_send_multicast_data()
1083 netdev_dbg(amt->dev, "no route to %pI4\n", &tunnel->ip4); in amt_send_multicast_data()
1103 amt->relay_port, in amt_send_multicast_data()
1109 static bool amt_send_membership_query(struct amt_dev *amt, in amt_send_membership_query() argument
1120 sock = rcu_dereference_bh(amt->sock); in amt_send_membership_query()
1124 err = skb_cow_head(skb, LL_RESERVED_SPACE(amt->dev) + sizeof(*amtmq) + in amt_send_membership_query()
1131 fl4.flowi4_oif = amt->stream_dev->ifindex; in amt_send_membership_query()
1133 fl4.saddr = amt->local_ip; in amt_send_membership_query()
1136 rt = ip_route_output_key(amt->net, &fl4); in amt_send_membership_query()
1138 netdev_dbg(amt->dev, "no route to %pI4\n", &tunnel->ip4); in amt_send_membership_query()
1161 amt->relay_port, in amt_send_membership_query()
1171 struct amt_dev *amt = netdev_priv(dev); in amt_dev_xmit() local
1245 if (amt->mode == AMT_MODE_GATEWAY) { in amt_dev_xmit()
1249 if ((!v6 && !READ_ONCE(amt->ready4)) || in amt_dev_xmit()
1250 (v6 && !READ_ONCE(amt->ready6))) in amt_dev_xmit()
1252 if (amt_send_membership_update(amt, skb, v6)) in amt_dev_xmit()
1255 } else if (amt->mode == AMT_MODE_RELAY) { in amt_dev_xmit()
1264 if (amt_send_membership_query(amt, skb, tunnel, v6)) in amt_dev_xmit()
1271 list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) { in amt_dev_xmit()
1288 amt_send_multicast_data(amt, skb, tunnel, v6); in amt_dev_xmit()
1321 struct amt_dev *amt = tunnel->amt; in amt_clear_groups() local
1328 for (i = 0; i < amt->hash_buckets; i++) in amt_clear_groups()
1330 amt_del_group(amt, gnode); in amt_clear_groups()
1340 struct amt_dev *amt = tunnel->amt; in amt_tunnel_expire() local
1342 spin_lock_bh(&amt->lock); in amt_tunnel_expire()
1345 amt->nr_tunnels--; in amt_tunnel_expire()
1348 spin_unlock_bh(&amt->lock); in amt_tunnel_expire()
1352 static void amt_cleanup_srcs(struct amt_dev *amt, in amt_cleanup_srcs() argument
1361 for (i = 0; i < amt->hash_buckets; i++) { in amt_cleanup_srcs()
1369 for (i = 0; i < amt->hash_buckets; i++) { in amt_cleanup_srcs()
1373 netdev_dbg(snode->gnode->amt->dev, in amt_cleanup_srcs()
1379 netdev_dbg(snode->gnode->amt->dev, in amt_cleanup_srcs()
1388 static void amt_add_srcs(struct amt_dev *amt, struct amt_tunnel_list *tunnel, in amt_add_srcs() argument
1414 if (tunnel->nr_sources >= amt->max_sources) in amt_add_srcs()
1434 netdev_dbg(snode->gnode->amt->dev, in amt_add_srcs()
1440 netdev_dbg(snode->gnode->amt->dev, in amt_add_srcs()
1476 struct amt_dev *amt = tunnel->amt; in amt_lookup_act_srcs() local
1519 for (i = 0; i < amt->hash_buckets; i++) { in amt_lookup_act_srcs()
1542 for (i = 0; i < amt->hash_buckets; i++) { in amt_lookup_act_srcs()
1587 netdev_dbg(amt->dev, "Invalid type\n"); in amt_lookup_act_srcs()
1592 static void amt_mcast_is_in_handler(struct amt_dev *amt, in amt_mcast_is_in_handler() argument
1645 static void amt_mcast_is_ex_handler(struct amt_dev *amt, in amt_mcast_is_ex_handler() argument
1674 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_is_ex_handler()
1675 dev_hold(amt->dev); in amt_mcast_is_ex_handler()
1703 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_is_ex_handler()
1704 dev_hold(amt->dev); in amt_mcast_is_ex_handler()
1709 static void amt_mcast_to_in_handler(struct amt_dev *amt, in amt_mcast_to_in_handler() argument
1770 static void amt_mcast_to_ex_handler(struct amt_dev *amt, in amt_mcast_to_ex_handler() argument
1800 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_to_ex_handler()
1801 dev_hold(amt->dev); in amt_mcast_to_ex_handler()
1830 msecs_to_jiffies(amt_gmi(amt)))) in amt_mcast_to_ex_handler()
1831 dev_hold(amt->dev); in amt_mcast_to_ex_handler()
1836 static void amt_mcast_allow_handler(struct amt_dev *amt, in amt_mcast_allow_handler() argument
1881 static void amt_mcast_block_handler(struct amt_dev *amt, in amt_mcast_block_handler() argument
1937 static void amt_igmpv2_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmpv2_report_handler() argument
1952 gnode = amt_add_group(amt, tunnel, &group, &host, false); in amt_igmpv2_report_handler()
1956 msecs_to_jiffies(amt_gmi(amt)))) in amt_igmpv2_report_handler()
1957 dev_hold(amt->dev); in amt_igmpv2_report_handler()
1974 static void amt_igmpv2_leave_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmpv2_leave_handler() argument
1989 amt_del_group(amt, gnode); in amt_igmpv2_leave_handler()
1992 static void amt_igmpv3_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmpv3_report_handler() argument
2023 gnode = amt_add_group(amt, tunnel, &group, &host, in amt_igmpv3_report_handler()
2029 amt_add_srcs(amt, tunnel, gnode, grec, false); in amt_igmpv3_report_handler()
2032 amt_mcast_is_in_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2036 amt_mcast_is_ex_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2040 amt_mcast_to_in_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2044 amt_mcast_to_ex_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2048 amt_mcast_allow_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2052 amt_mcast_block_handler(amt, tunnel, gnode, grec, in amt_igmpv3_report_handler()
2058 amt_cleanup_srcs(amt, tunnel, gnode); in amt_igmpv3_report_handler()
2063 static void amt_igmp_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_igmp_report_handler() argument
2070 amt_igmpv3_report_handler(amt, skb, tunnel); in amt_igmp_report_handler()
2073 amt_igmpv2_report_handler(amt, skb, tunnel); in amt_igmp_report_handler()
2076 amt_igmpv2_leave_handler(amt, skb, tunnel); in amt_igmp_report_handler()
2098 static void amt_mldv1_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mldv1_report_handler() argument
2111 gnode = amt_add_group(amt, tunnel, &group, &host, true); in amt_mldv1_report_handler()
2115 msecs_to_jiffies(amt_gmi(amt)))) in amt_mldv1_report_handler()
2116 dev_hold(amt->dev); in amt_mldv1_report_handler()
2135 static void amt_mldv1_leave_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mldv1_leave_handler() argument
2149 amt_del_group(amt, gnode); in amt_mldv1_leave_handler()
2154 static void amt_mldv2_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mldv2_report_handler() argument
2185 gnode = amt_add_group(amt, tunnel, &group, &host, in amt_mldv2_report_handler()
2191 amt_add_srcs(amt, tunnel, gnode, grec, true); in amt_mldv2_report_handler()
2194 amt_mcast_is_in_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2198 amt_mcast_is_ex_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2202 amt_mcast_to_in_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2206 amt_mcast_to_ex_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2210 amt_mcast_allow_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2214 amt_mcast_block_handler(amt, tunnel, gnode, grec, in amt_mldv2_report_handler()
2220 amt_cleanup_srcs(amt, tunnel, gnode); in amt_mldv2_report_handler()
2225 static void amt_mld_report_handler(struct amt_dev *amt, struct sk_buff *skb, in amt_mld_report_handler() argument
2232 amt_mldv1_report_handler(amt, skb, tunnel); in amt_mld_report_handler()
2235 amt_mldv2_report_handler(amt, skb, tunnel); in amt_mld_report_handler()
2238 amt_mldv1_leave_handler(amt, skb, tunnel); in amt_mld_report_handler()
2246 static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_advertisement_handler() argument
2266 if (amt->status != AMT_STATUS_SENT_DISCOVERY || in amt_advertisement_handler()
2267 amt->nonce != amta->nonce) in amt_advertisement_handler()
2270 amt->remote_ip = amta->ip4; in amt_advertisement_handler()
2271 netdev_dbg(amt->dev, "advertised remote ip = %pI4\n", &amt->remote_ip); in amt_advertisement_handler()
2272 mod_delayed_work(amt_wq, &amt->req_wq, 0); in amt_advertisement_handler()
2274 amt_update_gw_status(amt, AMT_STATUS_RECEIVED_ADVERTISEMENT, true); in amt_advertisement_handler()
2278 static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_multicast_data_handler() argument
2285 if (READ_ONCE(amt->status) != AMT_STATUS_SENT_UPDATE) in amt_multicast_data_handler()
2336 err = gro_cells_receive(&amt->gro_cells, skb); in amt_multicast_data_handler()
2338 dev_sw_netstats_rx_add(amt->dev, len); in amt_multicast_data_handler()
2340 amt->dev->stats.rx_dropped++; in amt_multicast_data_handler()
2345 static bool amt_membership_query_handler(struct amt_dev *amt, in amt_membership_query_handler() argument
2362 if (amtmq->nonce != amt->nonce) in amt_membership_query_handler()
2379 if (READ_ONCE(amt->ready4)) in amt_membership_query_handler()
2392 WRITE_ONCE(amt->ready4, true); in amt_membership_query_handler()
2393 amt->mac = amtmq->response_mac; in amt_membership_query_handler()
2394 amt->req_cnt = 0; in amt_membership_query_handler()
2395 amt->qi = ihv3->qqic; in amt_membership_query_handler()
2404 if (READ_ONCE(amt->ready6)) in amt_membership_query_handler()
2418 WRITE_ONCE(amt->ready6, true); in amt_membership_query_handler()
2419 amt->mac = amtmq->response_mac; in amt_membership_query_handler()
2420 amt->req_cnt = 0; in amt_membership_query_handler()
2421 amt->qi = mld2q->mld2q_qqic; in amt_membership_query_handler()
2436 amt_update_gw_status(amt, AMT_STATUS_RECEIVED_QUERY, true); in amt_membership_query_handler()
2437 dev_sw_netstats_rx_add(amt->dev, len); in amt_membership_query_handler()
2439 amt->dev->stats.rx_dropped++; in amt_membership_query_handler()
2446 static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_update_handler() argument
2469 list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) { in amt_update_handler()
2474 msecs_to_jiffies(amt_gmi(amt)) in amt_update_handler()
2478 netdev_dbg(amt->dev, "Invalid MAC\n"); in amt_update_handler()
2493 netdev_dbg(amt->dev, "Invalid IGMP\n"); in amt_update_handler()
2498 amt_igmp_report_handler(amt, skb, tunnel); in amt_update_handler()
2512 netdev_dbg(amt->dev, "Invalid MLD\n"); in amt_update_handler()
2517 amt_mld_report_handler(amt, skb, tunnel); in amt_update_handler()
2528 netdev_dbg(amt->dev, "Unsupported Protocol\n"); in amt_update_handler()
2539 dev_sw_netstats_rx_add(amt->dev, len); in amt_update_handler()
2541 amt->dev->stats.rx_dropped++; in amt_update_handler()
2547 static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce, in amt_send_advertisement() argument
2562 sock = rcu_dereference(amt->sock); in amt_send_advertisement()
2566 if (!netif_running(amt->stream_dev) || !netif_running(amt->dev)) in amt_send_advertisement()
2569 rt = ip_route_output_ports(amt->net, &fl4, sock->sk, in amt_send_advertisement()
2570 daddr, amt->local_ip, in amt_send_advertisement()
2571 dport, amt->relay_port, in amt_send_advertisement()
2573 amt->stream_dev->ifindex); in amt_send_advertisement()
2575 amt->dev->stats.tx_errors++; in amt_send_advertisement()
2579 hlen = LL_RESERVED_SPACE(amt->dev); in amt_send_advertisement()
2580 tlen = amt->dev->needed_tailroom; in amt_send_advertisement()
2582 skb = netdev_alloc_skb_ip_align(amt->dev, len); in amt_send_advertisement()
2585 amt->dev->stats.tx_errors++; in amt_send_advertisement()
2600 amta->ip4 = amt->local_ip; in amt_send_advertisement()
2604 udph->source = amt->relay_port; in amt_send_advertisement()
2610 udph->check = csum_tcpudp_magic(amt->local_ip, daddr, in amt_send_advertisement()
2622 iph->saddr = amt->local_ip; in amt_send_advertisement()
2627 ip_select_ident(amt->net, skb, NULL); in amt_send_advertisement()
2629 err = ip_local_out(amt->net, sock->sk, skb); in amt_send_advertisement()
2631 amt->dev->stats.tx_errors++; in amt_send_advertisement()
2637 static bool amt_discovery_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_discovery_handler() argument
2653 amt_send_advertisement(amt, amtd->nonce, iph->saddr, udph->source); in amt_discovery_handler()
2658 static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb) in amt_request_handler() argument
2678 list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) in amt_request_handler()
2682 spin_lock_bh(&amt->lock); in amt_request_handler()
2683 if (amt->nr_tunnels >= amt->max_tunnels) { in amt_request_handler()
2684 spin_unlock_bh(&amt->lock); in amt_request_handler()
2690 (sizeof(struct hlist_head) * amt->hash_buckets), in amt_request_handler()
2693 spin_unlock_bh(&amt->lock); in amt_request_handler()
2701 tunnel->amt = amt; in amt_request_handler()
2703 for (i = 0; i < amt->hash_buckets; i++) in amt_request_handler()
2708 list_add_tail_rcu(&tunnel->list, &amt->tunnel_list); in amt_request_handler()
2709 tunnel->key = amt->key; in amt_request_handler()
2711 amt->nr_tunnels++; in amt_request_handler()
2713 msecs_to_jiffies(amt_gmi(amt))); in amt_request_handler()
2714 spin_unlock_bh(&amt->lock); in amt_request_handler()
2724 if (!netif_running(amt->dev) || !netif_running(amt->stream_dev)) in amt_request_handler()
2728 amt_send_igmp_gq(amt, tunnel); in amt_request_handler()
2730 amt_send_mld_gq(amt, tunnel); in amt_request_handler()
2735 static void amt_gw_rcv(struct amt_dev *amt, struct sk_buff *skb) in amt_gw_rcv() argument
2743 if (amt->mode == AMT_MODE_GATEWAY) { in amt_gw_rcv()
2746 err = amt_advertisement_handler(amt, skb); in amt_gw_rcv()
2749 err = amt_membership_query_handler(amt, skb); in amt_gw_rcv()
2754 netdev_dbg(amt->dev, "Invalid type of Gateway\n"); in amt_gw_rcv()
2760 amt->dev->stats.rx_dropped++; in amt_gw_rcv()
2769 struct amt_dev *amt; in amt_rcv() local
2775 amt = rcu_dereference_sk_user_data(sk); in amt_rcv()
2776 if (!amt) { in amt_rcv()
2782 skb->dev = amt->dev; in amt_rcv()
2790 if (amt->mode == AMT_MODE_GATEWAY) { in amt_rcv()
2793 if (iph->saddr != amt->discovery_ip) { in amt_rcv()
2794 netdev_dbg(amt->dev, "Invalid Relay IP\n"); in amt_rcv()
2798 if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) { in amt_rcv()
2799 netdev_dbg(amt->dev, "AMT Event queue full\n"); in amt_rcv()
2805 if (iph->saddr != amt->remote_ip) { in amt_rcv()
2806 netdev_dbg(amt->dev, "Invalid Relay IP\n"); in amt_rcv()
2810 err = amt_multicast_data_handler(amt, skb); in amt_rcv()
2816 if (iph->saddr != amt->remote_ip) { in amt_rcv()
2817 netdev_dbg(amt->dev, "Invalid Relay IP\n"); in amt_rcv()
2821 if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) { in amt_rcv()
2822 netdev_dbg(amt->dev, "AMT Event queue full\n"); in amt_rcv()
2829 netdev_dbg(amt->dev, "Invalid type of Gateway\n"); in amt_rcv()
2835 err = amt_discovery_handler(amt, skb); in amt_rcv()
2838 err = amt_request_handler(amt, skb); in amt_rcv()
2841 err = amt_update_handler(amt, skb); in amt_rcv()
2848 netdev_dbg(amt->dev, "Invalid type of relay\n"); in amt_rcv()
2854 amt->dev->stats.rx_dropped++; in amt_rcv()
2866 struct amt_dev *amt = container_of(work, struct amt_dev, event_wq); in amt_event_work() local
2872 spin_lock_bh(&amt->lock); in amt_event_work()
2873 if (amt->nr_events == 0) { in amt_event_work()
2874 spin_unlock_bh(&amt->lock); in amt_event_work()
2877 event = amt->events[amt->event_idx].event; in amt_event_work()
2878 skb = amt->events[amt->event_idx].skb; in amt_event_work()
2879 amt->events[amt->event_idx].event = AMT_EVENT_NONE; in amt_event_work()
2880 amt->events[amt->event_idx].skb = NULL; in amt_event_work()
2881 amt->nr_events--; in amt_event_work()
2882 amt->event_idx++; in amt_event_work()
2883 amt->event_idx %= AMT_MAX_EVENTS; in amt_event_work()
2884 spin_unlock_bh(&amt->lock); in amt_event_work()
2888 amt_gw_rcv(amt, skb); in amt_event_work()
2891 amt_event_send_discovery(amt); in amt_event_work()
2894 amt_event_send_request(amt); in amt_event_work()
2905 struct amt_dev *amt; in amt_err_lookup() local
2909 amt = rcu_dereference_sk_user_data(sk); in amt_err_lookup()
2910 if (!amt) in amt_err_lookup()
2913 if (amt->mode != AMT_MODE_GATEWAY) in amt_err_lookup()
2920 netdev_dbg(amt->dev, "Received IGMP Unreachable of %s\n", in amt_err_lookup()
2927 if (READ_ONCE(amt->status) >= AMT_STATUS_RECEIVED_ADVERTISEMENT) in amt_err_lookup()
2928 mod_delayed_work(amt_wq, &amt->req_wq, 0); in amt_err_lookup()
2938 amt->dev->stats.rx_dropped++; in amt_err_lookup()
2961 static int amt_socket_create(struct amt_dev *amt) in amt_socket_create() argument
2966 sock = amt_create_sock(amt->net, amt->relay_port); in amt_socket_create()
2972 tunnel_cfg.sk_user_data = amt; in amt_socket_create()
2977 setup_udp_tunnel_sock(amt->net, sock, &tunnel_cfg); in amt_socket_create()
2979 rcu_assign_pointer(amt->sock, sock); in amt_socket_create()
2985 struct amt_dev *amt = netdev_priv(dev); in amt_dev_open() local
2988 amt->ready4 = false; in amt_dev_open()
2989 amt->ready6 = false; in amt_dev_open()
2990 amt->event_idx = 0; in amt_dev_open()
2991 amt->nr_events = 0; in amt_dev_open()
2993 err = amt_socket_create(amt); in amt_dev_open()
2997 amt->req_cnt = 0; in amt_dev_open()
2998 amt->remote_ip = 0; in amt_dev_open()
2999 amt->nonce = 0; in amt_dev_open()
3000 get_random_bytes(&amt->key, sizeof(siphash_key_t)); in amt_dev_open()
3002 amt->status = AMT_STATUS_INIT; in amt_dev_open()
3003 if (amt->mode == AMT_MODE_GATEWAY) { in amt_dev_open()
3004 mod_delayed_work(amt_wq, &amt->discovery_wq, 0); in amt_dev_open()
3005 mod_delayed_work(amt_wq, &amt->req_wq, 0); in amt_dev_open()
3006 } else if (amt->mode == AMT_MODE_RELAY) { in amt_dev_open()
3007 mod_delayed_work(amt_wq, &amt->secret_wq, in amt_dev_open()
3015 struct amt_dev *amt = netdev_priv(dev); in amt_dev_stop() local
3021 cancel_delayed_work_sync(&amt->req_wq); in amt_dev_stop()
3022 cancel_delayed_work_sync(&amt->discovery_wq); in amt_dev_stop()
3023 cancel_delayed_work_sync(&amt->secret_wq); in amt_dev_stop()
3026 sock = rtnl_dereference(amt->sock); in amt_dev_stop()
3027 RCU_INIT_POINTER(amt->sock, NULL); in amt_dev_stop()
3032 cancel_work_sync(&amt->event_wq); in amt_dev_stop()
3034 skb = amt->events[i].skb; in amt_dev_stop()
3036 amt->events[i].event = AMT_EVENT_NONE; in amt_dev_stop()
3037 amt->events[i].skb = NULL; in amt_dev_stop()
3040 amt->ready4 = false; in amt_dev_stop()
3041 amt->ready6 = false; in amt_dev_stop()
3042 amt->req_cnt = 0; in amt_dev_stop()
3043 amt->remote_ip = 0; in amt_dev_stop()
3045 list_for_each_entry_safe(tunnel, tmp, &amt->tunnel_list, list) { in amt_dev_stop()
3047 amt->nr_tunnels--; in amt_dev_stop()
3062 struct amt_dev *amt = netdev_priv(dev); in amt_dev_init() local
3065 amt->dev = dev; in amt_dev_init()
3070 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
3177 amt->net = net; in amt_newlink()
3178 amt->mode = nla_get_u32(data[IFLA_AMT_MODE]); in amt_newlink()
3182 amt->max_tunnels = nla_get_u32(data[IFLA_AMT_MAX_TUNNELS]); in amt_newlink()
3184 amt->max_tunnels = AMT_MAX_TUNNELS; in amt_newlink()
3186 spin_lock_init(&amt->lock); in amt_newlink()
3187 amt->max_groups = AMT_MAX_GROUP; in amt_newlink()
3188 amt->max_sources = AMT_MAX_SOURCE; in amt_newlink()
3189 amt->hash_buckets = AMT_HSIZE; in amt_newlink()
3190 amt->nr_tunnels = 0; in amt_newlink()
3191 get_random_bytes(&amt->hash_seed, sizeof(amt->hash_seed)); in amt_newlink()
3192 amt->stream_dev = dev_get_by_index(net, in amt_newlink()
3194 if (!amt->stream_dev) { in amt_newlink()
3200 if (amt->stream_dev->type != ARPHRD_ETHER) { in amt_newlink()
3206 amt->local_ip = nla_get_in_addr(data[IFLA_AMT_LOCAL_IP]); in amt_newlink()
3207 if (ipv4_is_loopback(amt->local_ip) || in amt_newlink()
3208 ipv4_is_zeronet(amt->local_ip) || in amt_newlink()
3209 ipv4_is_multicast(amt->local_ip)) { in amt_newlink()
3216 amt->relay_port = nla_get_be16(data[IFLA_AMT_RELAY_PORT]); in amt_newlink()
3218 amt->relay_port = htons(IANA_AMT_UDP_PORT); in amt_newlink()
3221 amt->gw_port = nla_get_be16(data[IFLA_AMT_GATEWAY_PORT]); in amt_newlink()
3223 amt->gw_port = htons(IANA_AMT_UDP_PORT); in amt_newlink()
3225 if (!amt->relay_port) { in amt_newlink()
3230 if (amt->mode == AMT_MODE_RELAY) { in amt_newlink()
3231 amt->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv); in amt_newlink()
3232 amt->qri = 10; in amt_newlink()
3233 dev->needed_headroom = amt->stream_dev->needed_headroom + in amt_newlink()
3235 dev->mtu = amt->stream_dev->mtu - AMT_RELAY_HLEN; in amt_newlink()
3244 if (!amt->gw_port) { in amt_newlink()
3249 amt->remote_ip = 0; in amt_newlink()
3250 amt->discovery_ip = nla_get_in_addr(data[IFLA_AMT_DISCOVERY_IP]); in amt_newlink()
3251 if (ipv4_is_loopback(amt->discovery_ip) || in amt_newlink()
3252 ipv4_is_zeronet(amt->discovery_ip) || in amt_newlink()
3253 ipv4_is_multicast(amt->discovery_ip)) { in amt_newlink()
3259 dev->needed_headroom = amt->stream_dev->needed_headroom + in amt_newlink()
3261 dev->mtu = amt->stream_dev->mtu - AMT_GW_HLEN; in amt_newlink()
3265 amt->qi = AMT_INIT_QUERY_INTERVAL; in amt_newlink()
3273 err = netdev_upper_dev_link(amt->stream_dev, dev, extack); in amt_newlink()
3279 INIT_DELAYED_WORK(&amt->discovery_wq, amt_discovery_work); in amt_newlink()
3280 INIT_DELAYED_WORK(&amt->req_wq, amt_req_work); in amt_newlink()
3281 INIT_DELAYED_WORK(&amt->secret_wq, amt_secret_work); in amt_newlink()
3282 INIT_WORK(&amt->event_wq, amt_event_work); in amt_newlink()
3283 INIT_LIST_HEAD(&amt->tunnel_list); in amt_newlink()
3286 dev_put(amt->stream_dev); in amt_newlink()
3292 struct amt_dev *amt = netdev_priv(dev); in amt_dellink() local
3295 netdev_upper_dev_unlink(amt->stream_dev, dev); in amt_dellink()
3296 dev_put(amt->stream_dev); in amt_dellink()
3313 struct amt_dev *amt = netdev_priv(dev); in amt_fill_info() local
3315 if (nla_put_u32(skb, IFLA_AMT_MODE, amt->mode)) in amt_fill_info()
3317 if (nla_put_be16(skb, IFLA_AMT_RELAY_PORT, amt->relay_port)) in amt_fill_info()
3319 if (nla_put_be16(skb, IFLA_AMT_GATEWAY_PORT, amt->gw_port)) in amt_fill_info()
3321 if (nla_put_u32(skb, IFLA_AMT_LINK, amt->stream_dev->ifindex)) in amt_fill_info()
3323 if (nla_put_in_addr(skb, IFLA_AMT_LOCAL_IP, amt->local_ip)) in amt_fill_info()
3325 if (nla_put_in_addr(skb, IFLA_AMT_DISCOVERY_IP, amt->discovery_ip)) in amt_fill_info()
3327 if (amt->remote_ip) in amt_fill_info()
3328 if (nla_put_in_addr(skb, IFLA_AMT_REMOTE_IP, amt->remote_ip)) in amt_fill_info()
3330 if (nla_put_u32(skb, IFLA_AMT_MAX_TUNNELS, amt->max_tunnels)) in amt_fill_info()
3355 struct amt_dev *amt; in amt_lookup_upper_dev() local
3359 amt = netdev_priv(upper_dev); in amt_lookup_upper_dev()
3360 if (amt->stream_dev == dev) in amt_lookup_upper_dev()
3373 struct amt_dev *amt; in amt_device_event() local
3380 amt = netdev_priv(upper_dev); in amt_device_event()
3384 amt_dellink(amt->dev, &list); in amt_device_event()
3388 if (amt->mode == AMT_MODE_RELAY) in amt_device_event()
3393 dev_set_mtu(amt->dev, new_mtu); in amt_device_event()