static int lw_nsnap_send(struct lw_psr_port_priv *psr_ppriv) { struct lw_nsnap_port_priv *nsnap_ppriv = lw_nsnap_ppriv_get(psr_ppriv); int err; struct sockaddr_ll ll_my; struct sockaddr_in6 sendto_addr; struct ns_packet nsp; err = teamd_getsockname_hwaddr(psr_ppriv->sock, &ll_my, sizeof(nsp.hwaddr)); if (err) return err; memset(&nsp, 0, sizeof(nsp)); /* setup ICMP6 header */ nsp.nsh.nd_ns_type = ND_NEIGHBOR_SOLICIT; nsp.nsh.nd_ns_cksum = 0; /* kernel computes this */ nsp.nsh.nd_ns_target = nsnap_ppriv->dst.sin6_addr; nsp.opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR; nsp.opt.nd_opt_len = 1; /* 8 bytes */ memcpy(nsp.hwaddr, ll_my.sll_addr, sizeof(nsp.hwaddr)); sendto_addr = nsnap_ppriv->dst; compute_multi_in6_addr(&sendto_addr.sin6_addr); sendto_addr.sin6_scope_id = psr_ppriv->common.tdport->ifindex; err = teamd_sendto(nsnap_ppriv->tx_sock, &nsp, sizeof(nsp), 0, (struct sockaddr *) &sendto_addr, sizeof(sendto_addr)); return err; }
static int lw_ap_send(struct lw_psr_port_priv *psr_ppriv) { struct lw_ap_port_priv *ap_ppriv = lw_ap_ppriv_get(psr_ppriv); int err; struct sockaddr_ll ll_my; struct sockaddr_ll ll_bcast; struct arp_packet ap; if (!(psr_ppriv->common.forced_send || ap_ppriv->send_always)) return 0; err = __get_port_curr_hwaddr(psr_ppriv, &ll_my, 0); if (err) return err; ll_bcast = ll_my; memset(ll_bcast.sll_addr, 0xFF, ll_bcast.sll_halen); memset(&ap, 0, sizeof(ap)); ap.ah.ar_hrd = htons(ll_my.sll_hatype); ap.ah.ar_pro = htons(ETH_P_IP); ap.ah.ar_hln = ll_my.sll_halen; ap.ah.ar_pln = 4; ap.ah.ar_op = htons(ARPOP_REQUEST); memcpy(ap.sender_mac, ll_my.sll_addr, sizeof(ap.sender_mac)); ap.sender_ip = ap_ppriv->src; memcpy(ap.target_mac, ll_bcast.sll_addr, sizeof(ap.target_mac)); ap.target_ip = ap_ppriv->dst; if (ap_ppriv->vlanid_in_use) { struct arp_vlan_packet avp; avp.ap = ap; avp.vlanh.h_vlan_encapsulated_proto = htons(ETH_P_ARP); avp.vlanh.h_vlan_TCI = htons(ap_ppriv->vlanid); ll_bcast.sll_protocol = htons(ETH_P_8021Q); return teamd_sendto(psr_ppriv->sock, &avp, sizeof(avp), 0, (struct sockaddr *) &ll_bcast, sizeof(ll_bcast)); } else { return teamd_sendto(psr_ppriv->sock, &ap, sizeof(ap), 0, (struct sockaddr *) &ll_bcast, sizeof(ll_bcast)); } }