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 __get_port_curr_hwaddr(struct lw_psr_port_priv *psr_ppriv, struct sockaddr_ll *addr, size_t expected_len) { struct team_ifinfo *ifinfo = psr_ppriv->common.tdport->team_ifinfo; size_t port_hwaddr_len = team_get_ifinfo_hwaddr_len(ifinfo); char *port_hwaddr = team_get_ifinfo_hwaddr(ifinfo); int err; err = teamd_getsockname_hwaddr(psr_ppriv->sock, addr, expected_len); if (err) return err; if ((addr->sll_halen != port_hwaddr_len) || (expected_len && expected_len != port_hwaddr_len)) { teamd_log_err("Unexpected length of hw address."); return -ENOTSUP; } memcpy(addr->sll_addr, port_hwaddr, addr->sll_halen); return 0; }