} else {
memset(&shop, 0, sizeof(shop));
shop.peer = bpc->bpc_peer;
- if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif)
+ if (bpc->bpc_has_localif)
strlcpy(shop.port_name, bpc->bpc_localif,
sizeof(shop.port_name));
return l_bfd;
}
-#if 0 /* TODO VxLAN Support */
-static void
-_update_vxlan_sess_parms(struct bfd_session *bfd, bfd_sess_parms *sess_parms)
-{
- struct bfd_session_vxlan_info *vxlan_info = &bfd->vxlan_info;
- bfd_parms_list *parms = &sess_parms->parms;
-
- vxlan_info->vnid = parms->vnid;
- vxlan_info->check_tnl_key = parms->check_tnl_key;
- vxlan_info->forwarding_if_rx = parms->forwarding_if_rx;
- vxlan_info->cpath_down = parms->cpath_down;
- vxlan_info->decay_min_rx = parms->decay_min_rx;
-
- inet_aton(parms->local_dst_ip, &vxlan_info->local_dst_ip);
- inet_aton(parms->remote_dst_ip, &vxlan_info->peer_dst_ip);
-
- memcpy(vxlan_info->local_dst_mac, parms->local_dst_mac, ETH_ALEN);
- memcpy(vxlan_info->peer_dst_mac, parms->remote_dst_mac, ETH_ALEN);
-
- /* The interface may change for Vxlan BFD sessions, so update
- * the local mac and ifindex
- */
- bfd->ifindex = sess_parms->ifindex;
- memcpy(bfd->local_mac, sess_parms->local_mac, sizeof(bfd->local_mac));
-}
-#endif /* VxLAN support */
-
int bfd_xmt_cb(struct thread *t)
{
struct bfd_session *bs = THREAD_ARG(t);
_bfd_session_update(bs, bpc);
- /* TODO add VxLAN support. */
-
control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs);
return 0;
ptm_bfd_fetch_local_mac(bpc->bpc_localif, bfd->local_mac);
}
- if (bpc->bpc_has_vxlan)
- BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN);
-
if (bpc->bpc_ipv4 == false) {
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
bfd_mhop_insert(bfd);
} else {
bfd->shop.peer = bpc->bpc_peer;
- if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif)
+ if (bpc->bpc_has_localif)
strlcpy(bfd->shop.port_name, bpc->bpc_localif,
sizeof(bfd->shop.port_name));
bfd_shop_insert(bfd);
}
- if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) {
- static uint8_t bfd_def_vxlan_dmac[] = {0x00, 0x23, 0x20,
- 0x00, 0x00, 0x01};
- memcpy(bfd->peer_mac, bfd_def_vxlan_dmac,
- sizeof(bfd_def_vxlan_dmac));
- }
-#if 0 /* TODO */
- else if (event->rmac) {
- if (sscanf(event->rmac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
- &bfd->peer_mac[0], &bfd->peer_mac[1], &bfd->peer_mac[2],
- &bfd->peer_mac[3], &bfd->peer_mac[4], &bfd->peer_mac[5])
- != 6)
- DLOG("%s: Assigning remote mac = %s", __func__,
- event->rmac);
- }
-#endif
-
/*
* XXX: session update triggers echo start, so we must have our
* discriminator ID set first.
/*
* Definitions
*/
-
-/* iov for BFD control frames */
-#define CMSG_HDR_LEN sizeof(struct cmsghdr)
-#define CMSG_TTL_LEN (CMSG_HDR_LEN + sizeof(uint32_t))
-#define CMSG_IN_PKT_INFO_LEN (CMSG_HDR_LEN + sizeof(struct in_pktinfo) + 4)
-#define CMSG_IN6_PKT_INFO_LEN \
- (CMSG_HDR_LEN + sizeof(struct in6_addr) + sizeof(int) + 4)
-
struct bfd_raw_echo_pkt {
#ifdef BFD_LINUX
struct iphdr ip;
struct bfd_echo_pkt data;
};
-#if 0 /* TODO: VxLAN support. */
-struct bfd_raw_ctrl_pkt {
- struct iphdr ip;
- struct udphdr udp;
- struct bfd_pkt data;
-};
-#endif
-
-struct vxlan_hdr {
- uint32_t flags;
- uint32_t vnid;
-};
-
#define IP_ECHO_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN)
#define UDP_ECHO_PKT_LEN (UDP_HDR_LEN + BFD_ECHO_PKT_LEN)
-#define IP_CTRL_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_PKT_LEN)
-#define UDP_CTRL_PKT_LEN (UDP_HDR_LEN + BFD_PKT_LEN)
static uint8_t msgbuf[BFD_PKT_LEN];
+
/*
* Prototypes
*/
static void ptm_bfd_echo_pkt_create(struct bfd_session *bfd);
static int ptm_bfd_echo_loopback(uint8_t *pkt, int pkt_len, struct sockaddr *ss,
socklen_t sslen);
-static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd, int fbit);
static int ptm_bfd_process_echo_pkt(int s);
-static bool
-ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd,
- struct bfd_session_vxlan_info *vxlan_info);
static void bfd_sd_reschedule(int sd);
static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
sa = (struct sockaddr *)&dll;
slen = sizeof(dll);
#else
- /*
- * TODO: implement layer 2 send for *BSDs. This is
- * needed for VxLAN.
- */
+ /* TODO: implement layer 2 send for *BSDs. */
log_warning("packet-send: not implemented");
return -1;
#endif
return 0;
}
-static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd
- __attribute__((__unused__)),
- int fbit __attribute__((__unused__)))
-{
-#if 0 /* TODO: VxLAN support. */
- struct bfd_raw_ctrl_pkt cp;
- uint8_t vxlan_pkt[BFD_VXLAN_PKT_TOT_LEN];
- uint8_t *pkt = vxlan_pkt;
- struct sockaddr_in sin;
- struct vxlan_hdr *vhdr;
-
- memset(vxlan_pkt, 0, sizeof(vxlan_pkt));
- memset(&cp, 0, sizeof(cp));
-
- /* Construct VxLAN header information */
- vhdr = (struct vxlan_hdr *)pkt;
- vhdr->flags = htonl(0x08000000);
- vhdr->vnid = htonl(bfd->vxlan_info.vnid << 8);
- pkt += VXLAN_HDR_LEN;
-
- /* Construct ethernet header information */
- memcpy(pkt, bfd->vxlan_info.peer_dst_mac, ETHERNET_ADDRESS_LENGTH);
- pkt = pkt + ETHERNET_ADDRESS_LENGTH;
- memcpy(pkt, bfd->vxlan_info.local_dst_mac, ETHERNET_ADDRESS_LENGTH);
- pkt = pkt + ETHERNET_ADDRESS_LENGTH;
- pkt[0] = ETH_P_IP / 256;
- pkt[1] = ETH_P_IP % 256;
- pkt += 2;
-
- /* Construct IP header information */
- cp.ip.version = 4;
- cp.ip.ihl = 5;
- cp.ip.tos = 0;
- cp.ip.tot_len = htons(IP_CTRL_PKT_LEN);
- cp.ip.id = ptm_bfd_gen_IP_ID(bfd);
- cp.ip.frag_off = 0;
- cp.ip.ttl = BFD_TTL_VAL;
- cp.ip.protocol = IPPROTO_UDP;
- cp.ip.daddr = bfd->vxlan_info.peer_dst_ip.s_addr;
- cp.ip.saddr = bfd->vxlan_info.local_dst_ip.s_addr;
- cp.ip.check = checksum((uint16_t *)&cp.ip, IP_HDR_LEN);
-
- /* Construct UDP header information */
- cp.udp.source = htons(BFD_DEFDESTPORT);
- cp.udp.dest = htons(BFD_DEFDESTPORT);
- cp.udp.len = htons(UDP_CTRL_PKT_LEN);
-
- /* Construct BFD control packet information */
- cp.data.diag = bfd->local_diag;
- BFD_SETVER(cp.data.diag, BFD_VERSION);
- BFD_SETSTATE(cp.data.flags, bfd->ses_state);
- BFD_SETDEMANDBIT(cp.data.flags, BFD_DEF_DEMAND);
- BFD_SETPBIT(cp.data.flags, bfd->polling);
- BFD_SETFBIT(cp.data.flags, fbit);
- cp.data.detect_mult = bfd->detect_mult;
- cp.data.len = BFD_PKT_LEN;
- cp.data.discrs.my_discr = htonl(bfd->discrs.my_discr);
- cp.data.discrs.remote_discr = htonl(bfd->discrs.remote_discr);
- cp.data.timers.desired_min_tx = htonl(bfd->timers.desired_min_tx);
- cp.data.timers.required_min_rx = htonl(bfd->timers.required_min_rx);
- cp.data.timers.required_min_echo = htonl(bfd->timers.required_min_echo);
-
- cp.udp.check =
- udp4_checksum(&cp.ip, (uint8_t *)&cp.udp, UDP_CTRL_PKT_LEN);
-
- memcpy(pkt, &cp, sizeof(cp));
- sin.sin_family = AF_INET;
- sin.sin_addr = bfd->shop.peer.sa_sin.sin_addr;
- sin.sin_port = htons(4789);
-
- if (sendto(bfd->sock, vxlan_pkt, BFD_VXLAN_PKT_TOT_LEN, 0,
- (struct sockaddr *)&sin, sizeof(struct sockaddr_in))
- < 0) {
- ERRLOG("Error sending vxlan bfd pkt: %s", strerror(errno));
- } else {
- bfd->stats.tx_ctrl_pkt++;
- }
-#endif
-}
-
static int ptm_bfd_process_echo_pkt(int s)
{
uint32_t my_discr = 0;
{
struct bfd_pkt cp;
- /* if the BFD session is for VxLAN tunnel, then construct and
- * send bfd raw packet
- */
- if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) {
- ptm_bfd_vxlan_pkt_snd(bfd, fbit);
- return;
- }
-
/* Set fields according to section 6.5.7 */
cp.diag = bfd->local_diag;
BFD_SETVER(cp.diag, BFD_VERSION);
bfd->stats.tx_ctrl_pkt++;
}
-#if 0 /* TODO VxLAN Support */
-static struct bfd_pkt *
-ptm_bfd_process_vxlan_pkt(int s, ptm_sockevent_e se, void *udata, int *ifindex,
- struct sockaddr_in *sin,
- struct bfd_session_vxlan_info_t *vxlan_info,
- uint8_t *rx_pkt, int *mlen)
-{
- struct sockaddr_ll sll;
- uint32_t from_len = sizeof(struct sockaddr_ll);
- struct bfd_raw_ctrl_pkt *cp;
- uint8_t *pkt = rx_pkt;
- struct iphdr *iph;
- struct ethhdr *inner_ethh;
-
- *mlen = recvfrom(s, rx_pkt, BFD_RX_BUF_LEN, MSG_DONTWAIT,
- (struct sockaddr *)&sll, &from_len);
-
- if (*mlen < 0) {
- if (errno != EAGAIN)
- ERRLOG("Error receiving from BFD Vxlan socket %d: %m",
- s);
- return NULL;
- }
-
- iph = (struct iphdr *)(pkt + ETH_HDR_LEN);
- pkt = pkt + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN;
- vxlan_info->vnid = ntohl(*((int *)(pkt + 4)));
- vxlan_info->vnid = vxlan_info->vnid >> 8;
-
- pkt = pkt + VXLAN_HDR_LEN;
- inner_ethh = (struct ethhdr *)pkt;
-
- cp = (struct bfd_raw_ctrl_pkt *)(pkt + ETH_HDR_LEN);
-
- /* Discard the non BFD packets */
- if (ntohs(cp->udp.dest) != BFD_DEFDESTPORT)
- return NULL;
-
- *ifindex = sll.sll_ifindex;
- sin->sin_addr.s_addr = iph->saddr;
- sin->sin_port = ntohs(cp->udp.dest);
-
- vxlan_info->local_dst_ip.s_addr = cp->ip.daddr;
- memcpy(vxlan_info->local_dst_mac, inner_ethh->h_dest,
- ETHERNET_ADDRESS_LENGTH);
-
- return &cp->data;
-}
-#endif /* VxLAN */
-
-static bool
-ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd,
- struct bfd_session_vxlan_info *vxlan_info)
-{
- if (bfd->vxlan_info.check_tnl_key && (vxlan_info->vnid != 0)) {
- log_error("vxlan-packet: vnid not zero: %d", vxlan_info->vnid);
- return false;
- }
-
- if (bfd->vxlan_info.local_dst_ip.s_addr
- != vxlan_info->local_dst_ip.s_addr) {
- log_error("vxlan-packet: wrong inner destination",
- inet_ntoa(vxlan_info->local_dst_ip));
- return false;
- }
-
- if (memcmp(bfd->vxlan_info.local_dst_mac, vxlan_info->local_dst_mac,
- ETHERNET_ADDRESS_LENGTH)) {
- log_error(
- "vxlan-packet: wrong inner mac: %02x:%02x:%02x:%02x:%02x:%02x",
- vxlan_info->local_dst_mac[0],
- vxlan_info->local_dst_mac[1],
- vxlan_info->local_dst_mac[2],
- vxlan_info->local_dst_mac[3],
- vxlan_info->local_dst_mac[4],
- vxlan_info->local_dst_mac[5]);
- return false;
- }
-
- return true;
-}
-
static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
char *vrfname, size_t vrfnamelen,
struct sockaddr_any *local,
bglobal.bg_ev[4] = NULL;
thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo,
&bglobal.bg_ev[4]);
- } else if (sd == bglobal.bg_vxlan) {
- bglobal.bg_ev[5] = NULL;
- thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan,
- &bglobal.bg_ev[5]);
}
}
int sd = THREAD_FD(t);
struct bfd_session *bfd;
struct bfd_pkt *cp;
- bool is_mhop, is_vxlan;
+ bool is_mhop;
ssize_t mlen = 0;
uint32_t oldEchoXmt_TO, oldXmtTime;
struct sockaddr_any local, peer;
char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1];
- struct bfd_session_vxlan_info vxlan_info;
/* Schedule next read. */
bfd_sd_reschedule(sd);
memset(&peer, 0, sizeof(peer));
/* Handle control packets. */
- is_mhop = is_vxlan = false;
+ is_mhop = false;
if (sd == bglobal.bg_shop || sd == bglobal.bg_mhop) {
is_mhop = sd == bglobal.bg_mhop;
mlen = bfd_recv_ipv4(sd, is_mhop, port, sizeof(port), vrfname,
mlen = bfd_recv_ipv6(sd, is_mhop, port, sizeof(port), vrfname,
sizeof(vrfname), &local, &peer);
}
-#if 0 /* TODO vxlan handling */
- cp = ptm_bfd_process_vxlan_pkt(s, se, udata, &local_ifindex,
- &sin, &vxlan_info, rx_pkt, &mlen);
- if (!cp)
- return -1;
-
- is_vxlan = true;
- /* keep in network-byte order */
- peer.ip4_addr.s_addr = sin.sin_addr.s_addr;
- peer.family = AF_INET;
- strcpy(peer_addr, inet_ntoa(sin.sin_addr));
-#endif
/* Implement RFC 5880 6.8.6 */
if (mlen < BFD_PKT_LEN) {
return 0;
}
- /* Handle VxLAN cases. */
- if (is_vxlan && !ptm_bfd_validate_vxlan_pkt(bfd, &vxlan_info))
- return 0;
-
bfd->stats.rx_ctrl_pkt++;
/*
return -1;
}
- if (!bpc->bpc_has_vxlan) {
- /* Set TTL to 255 for all transmitted packets */
- if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) {
- close(sd);
- return -1;
- }
+ /* Set TTL to 255 for all transmitted packets */
+ if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) {
+ close(sd);
+ return -1;
}
/* Set TOS to CS6 for all transmitted packets */
return -1;
}
- /* dont bind-to-device incase of vxlan */
- if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) {
+ if (bpc->bpc_has_localif) {
if (bp_bind_dev(sd, bpc->bpc_localif) != 0) {
close(sd);
return -1;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin.sin_len = sizeof(sin);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
- if (bpc->bpc_mhop || bpc->bpc_has_vxlan)
+ if (bpc->bpc_mhop)
sin.sin_addr = bpc->bpc_local.sa_sin.sin_addr;
else
sin.sin_addr.s_addr = INADDR_ANY;
return -1;
}
- if (!bpc->bpc_has_vxlan) {
- /* Set TTL to 255 for all transmitted packets */
- if (bp_set_ttlv6(sd, BFD_TTL_VAL) != 0) {
- close(sd);
- return -1;
- }
+ /* Set TTL to 255 for all transmitted packets */
+ if (bp_set_ttlv6(sd, BFD_TTL_VAL) != 0) {
+ close(sd);
+ return -1;
}
/* Set TOS to CS6 for all transmitted packets */
{0x6, 0, 0, 0x0000ffff}, {0x6, 0, 0, 0x00000000},
};
-/* Berkeley Packet filter code to filter out BFD vxlan packets.
- * tcpdump -dd "(udp dst port 4789)"
- */
-static struct sock_filter bfd_vxlan_filter[] = {
- {0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd},
- {0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011},
- {0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x000012b5},
- {0x15, 0, 8, 0x00000800}, {0x30, 0, 0, 0x00000017},
- {0x15, 0, 6, 0x00000011}, {0x28, 0, 0, 0x00000014},
- {0x45, 4, 0, 0x00001fff}, {0xb1, 0, 0, 0x0000000e},
- {0x48, 0, 0, 0x00000010}, {0x15, 0, 1, 0x000012b5},
- {0x6, 0, 0, 0x0000ffff}, {0x6, 0, 0, 0x00000000},
-};
-
/*
* Definitions.
return s;
}
-int ptm_bfd_vxlan_sock_init(void)
-{
- int s;
- struct sock_fprog bpf = {.len = sizeof(bfd_vxlan_filter)
- / sizeof(bfd_vxlan_filter[0]),
- .filter = bfd_vxlan_filter};
-
- s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
- if (s == -1) {
- log_error("vxlan-socket: creation failure: %s",
- strerror(errno));
- return -1;
- }
-
- if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))
- == -1) {
- log_error("vxlan-socket: setsockopt(SO_ATTACH_FILTER): %s",
- strerror(errno));
- close(s);
- return -1;
- }
-
- return s;
-}
-
int bp_bind_dev(int sd __attribute__((__unused__)),
const char *dev __attribute__((__unused__)))
{