mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 00:41:20 +00:00
Merge pull request #2959 from opensourcerouting/bfd-cleanup
bfdd: code clean up
This commit is contained in:
commit
c279fc5fdd
57
bfdd/bfd.c
57
bfdd/bfd.c
@ -78,7 +78,7 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
|
||||
} 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));
|
||||
|
||||
@ -311,33 +311,6 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *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);
|
||||
@ -364,7 +337,7 @@ int bfd_recvtimer_cb(struct thread *t)
|
||||
switch (bs->ses_state) {
|
||||
case PTM_BFD_INIT:
|
||||
case PTM_BFD_UP:
|
||||
ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME);
|
||||
ptm_bfd_ses_dn(bs, BD_CONTROL_EXPIRED);
|
||||
bfd_recvtimer_update(bs);
|
||||
break;
|
||||
|
||||
@ -387,7 +360,7 @@ int bfd_echo_recvtimer_cb(struct thread *t)
|
||||
switch (bs->ses_state) {
|
||||
case PTM_BFD_INIT:
|
||||
case PTM_BFD_UP:
|
||||
ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME);
|
||||
ptm_bfd_ses_dn(bs, BD_ECHO_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -535,8 +508,6 @@ static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc)
|
||||
|
||||
_bfd_session_update(bs, bpc);
|
||||
|
||||
/* TODO add VxLAN support. */
|
||||
|
||||
control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs);
|
||||
|
||||
return 0;
|
||||
@ -606,9 +577,6 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
||||
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);
|
||||
|
||||
@ -644,30 +612,13 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
||||
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.
|
||||
|
87
bfdd/bfd.h
87
bfdd/bfd.h
@ -105,9 +105,6 @@ struct bfd_echo_pkt {
|
||||
#define BFD_CBIT 0x08
|
||||
#define BFD_ABIT 0x04
|
||||
#define BFD_DEMANDBIT 0x02
|
||||
#define BFD_DIAGNEIGHDOWN 3
|
||||
#define BFD_DIAGDETECTTIME 1
|
||||
#define BFD_DIAGADMINDOWN 7
|
||||
#define BFD_SETDEMANDBIT(flags, val) \
|
||||
{ \
|
||||
if ((val)) \
|
||||
@ -133,18 +130,27 @@ struct bfd_echo_pkt {
|
||||
#define BFD_GETSTATE(flags) ((flags >> 6) & 0x3)
|
||||
#define BFD_ECHO_VERSION 1
|
||||
#define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt)
|
||||
#define BFD_CTRL_PKT_LEN sizeof(struct bfd_pkt)
|
||||
#define IP_HDR_LEN 20
|
||||
#define UDP_HDR_LEN 8
|
||||
#define ETH_HDR_LEN 14
|
||||
#define VXLAN_HDR_LEN 8
|
||||
#define HEADERS_MIN_LEN (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN)
|
||||
#define BFD_ECHO_PKT_TOT_LEN \
|
||||
((int)(ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN))
|
||||
#define BFD_VXLAN_PKT_TOT_LEN \
|
||||
((int)(VXLAN_HDR_LEN + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN \
|
||||
+ BFD_CTRL_PKT_LEN))
|
||||
#define BFD_RX_BUF_LEN 160
|
||||
|
||||
enum bfd_diagnosticis {
|
||||
BD_OK = 0,
|
||||
/* Control Detection Time Expired. */
|
||||
BD_CONTROL_EXPIRED = 1,
|
||||
/* Echo Function Failed. */
|
||||
BD_ECHO_FAILED = 2,
|
||||
/* Neighbor Signaled Session Down. */
|
||||
BD_NEIGHBOR_DOWN = 3,
|
||||
/* Forwarding Plane Reset. */
|
||||
BD_FORWARDING_RESET = 4,
|
||||
/* Path Down. */
|
||||
BD_PATH_DOWN = 5,
|
||||
/* Concatenated Path Down. */
|
||||
BD_CONCATPATH_DOWN = 6,
|
||||
/* Administratively Down. */
|
||||
BD_ADMIN_DOWN = 7,
|
||||
/* Reverse Concatenated Path Down. */
|
||||
BD_REVCONCATPATH_DOWN = 8,
|
||||
/* 9..31: reserved. */
|
||||
};
|
||||
|
||||
/* BFD session flags */
|
||||
enum bfd_session_flags {
|
||||
@ -154,9 +160,6 @@ enum bfd_session_flags {
|
||||
* actively
|
||||
*/
|
||||
BFD_SESS_FLAG_MH = 1 << 2, /* BFD Multi-hop session */
|
||||
BFD_SESS_FLAG_VXLAN = 1 << 3, /* BFD Multi-hop session which is
|
||||
* used to monitor vxlan tunnel
|
||||
*/
|
||||
BFD_SESS_FLAG_IPV6 = 1 << 4, /* BFD IPv6 session */
|
||||
BFD_SESS_FLAG_SEND_EVT_ACTIVE = 1 << 5, /* send event timer active */
|
||||
BFD_SESS_FLAG_SEND_EVT_IGNORE = 1 << 6, /* ignore send event when timer
|
||||
@ -191,18 +194,6 @@ struct bfd_session_stats {
|
||||
uint64_t znotification;
|
||||
};
|
||||
|
||||
struct bfd_session_vxlan_info {
|
||||
uint32_t vnid;
|
||||
uint32_t decay_min_rx;
|
||||
uint8_t forwarding_if_rx;
|
||||
uint8_t cpath_down;
|
||||
uint8_t check_tnl_key;
|
||||
uint8_t local_dst_mac[ETHERNET_ADDRESS_LENGTH];
|
||||
uint8_t peer_dst_mac[ETHERNET_ADDRESS_LENGTH];
|
||||
struct in_addr local_dst_ip;
|
||||
struct in_addr peer_dst_ip;
|
||||
};
|
||||
|
||||
/* bfd_session shortcut label forwarding. */
|
||||
struct peer_label;
|
||||
|
||||
@ -249,16 +240,11 @@ struct bfd_session {
|
||||
int ifindex;
|
||||
uint8_t local_mac[ETHERNET_ADDRESS_LENGTH];
|
||||
uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH];
|
||||
uint16_t ip_id;
|
||||
|
||||
/* BFD session flags */
|
||||
enum bfd_session_flags flags;
|
||||
|
||||
uint8_t echo_pkt[BFD_ECHO_PKT_TOT_LEN]; /* Save the Echo Packet
|
||||
* which will be transmitted
|
||||
*/
|
||||
struct bfd_session_stats stats;
|
||||
struct bfd_session_vxlan_info vxlan_info;
|
||||
|
||||
struct timeval uptime; /* last up time */
|
||||
struct timeval downtime; /* last down time */
|
||||
@ -407,7 +393,7 @@ struct bfd_global {
|
||||
int bg_shop6;
|
||||
int bg_mhop6;
|
||||
int bg_echo;
|
||||
int bg_vxlan;
|
||||
int bg_echov6;
|
||||
struct thread *bg_ev[6];
|
||||
|
||||
int bg_csock;
|
||||
@ -473,10 +459,10 @@ void log_fatal(const char *fmt, ...);
|
||||
*
|
||||
* Contains the code related with receiving/seding, packing/unpacking BFD data.
|
||||
*/
|
||||
int bp_set_ttlv6(int sd);
|
||||
int bp_set_ttl(int sd);
|
||||
int bp_set_tosv6(int sd);
|
||||
int bp_set_tos(int sd);
|
||||
int bp_set_ttlv6(int sd, uint8_t value);
|
||||
int bp_set_ttl(int sd, uint8_t value);
|
||||
int bp_set_tosv6(int sd, uint8_t value);
|
||||
int bp_set_tos(int sd, uint8_t value);
|
||||
int bp_bind_dev(int sd, const char *dev);
|
||||
|
||||
int bp_udp_shop(void);
|
||||
@ -485,14 +471,14 @@ int bp_udp6_shop(void);
|
||||
int bp_udp6_mhop(void);
|
||||
int bp_peer_socket(struct bfd_peer_cfg *bpc);
|
||||
int bp_peer_socketv6(struct bfd_peer_cfg *bpc);
|
||||
int bp_echo_socket(void);
|
||||
int bp_echov6_socket(void);
|
||||
|
||||
void ptm_bfd_snd(struct bfd_session *bfd, int fbit);
|
||||
void ptm_bfd_echo_snd(struct bfd_session *bfd);
|
||||
|
||||
int bfd_recv_cb(struct thread *t);
|
||||
|
||||
uint16_t checksum(uint16_t *buf, int len);
|
||||
|
||||
|
||||
/*
|
||||
* event.c
|
||||
@ -602,30 +588,13 @@ int ptm_bfd_notify(struct bfd_session *bs);
|
||||
/*
|
||||
* OS compatibility functions.
|
||||
*/
|
||||
struct udp_psuedo_header {
|
||||
uint32_t saddr;
|
||||
uint32_t daddr;
|
||||
uint8_t reserved;
|
||||
uint8_t protocol;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
#define UDP_PSUEDO_HDR_LEN sizeof(struct udp_psuedo_header)
|
||||
|
||||
#if defined(BFD_LINUX) || defined(BFD_BSD)
|
||||
int ptm_bfd_fetch_ifindex(const char *ifname);
|
||||
void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac);
|
||||
void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen);
|
||||
int ptm_bfd_echo_sock_init(void);
|
||||
int ptm_bfd_vxlan_sock_init(void);
|
||||
#endif /* BFD_LINUX || BFD_BSD */
|
||||
|
||||
#ifdef BFD_LINUX
|
||||
uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len);
|
||||
#endif /* BFD_LINUX */
|
||||
|
||||
#ifdef BFD_BSD
|
||||
uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len);
|
||||
ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen,
|
||||
struct sockaddr_storage *ss, socklen_t *sslen,
|
||||
uint8_t *ttl, uint32_t *id);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,9 +66,6 @@ struct bfd_peer_cfg {
|
||||
bool bpc_has_label;
|
||||
char bpc_label[MAXNAMELEN];
|
||||
|
||||
bool bpc_has_vxlan;
|
||||
unsigned int bpc_vxlan;
|
||||
|
||||
bool bpc_has_localif;
|
||||
char bpc_localif[MAXNAMELEN + 1];
|
||||
|
||||
|
28
bfdd/bfdd.c
28
bfdd/bfdd.c
@ -90,7 +90,6 @@ static void sigterm_handler(void)
|
||||
socket_close(&bglobal.bg_mhop);
|
||||
socket_close(&bglobal.bg_shop6);
|
||||
socket_close(&bglobal.bg_mhop6);
|
||||
socket_close(&bglobal.bg_vxlan);
|
||||
|
||||
/* Terminate and free() FRR related memory. */
|
||||
frr_fini();
|
||||
@ -131,17 +130,22 @@ static struct option longopts[] = {
|
||||
struct bfd_global bglobal;
|
||||
|
||||
struct bfd_diag_str_list diag_list[] = {
|
||||
{.str = "NeighDown", .type = BFD_DIAGNEIGHDOWN},
|
||||
{.str = "DetectTime", .type = BFD_DIAGDETECTTIME},
|
||||
{.str = "AdminDown", .type = BFD_DIAGADMINDOWN},
|
||||
{.str = "control-expired", .type = BD_CONTROL_EXPIRED},
|
||||
{.str = "echo-failed", .type = BD_ECHO_FAILED},
|
||||
{.str = "neighbor-down", .type = BD_NEIGHBOR_DOWN},
|
||||
{.str = "forwarding-reset", .type = BD_FORWARDING_RESET},
|
||||
{.str = "path-down", .type = BD_PATH_DOWN},
|
||||
{.str = "concatenated-path-down", .type = BD_CONCATPATH_DOWN},
|
||||
{.str = "administratively-down", .type = BD_ADMIN_DOWN},
|
||||
{.str = "reverse-concat-path-down", .type = BD_REVCONCATPATH_DOWN},
|
||||
{.str = NULL},
|
||||
};
|
||||
|
||||
struct bfd_state_str_list state_list[] = {
|
||||
{.str = "AdminDown", .type = PTM_BFD_ADM_DOWN},
|
||||
{.str = "Down", .type = PTM_BFD_DOWN},
|
||||
{.str = "Init", .type = PTM_BFD_INIT},
|
||||
{.str = "Up", .type = PTM_BFD_UP},
|
||||
{.str = "admin-down", .type = PTM_BFD_ADM_DOWN},
|
||||
{.str = "down", .type = PTM_BFD_DOWN},
|
||||
{.str = "init", .type = PTM_BFD_INIT},
|
||||
{.str = "up", .type = PTM_BFD_UP},
|
||||
{.str = NULL},
|
||||
};
|
||||
|
||||
@ -154,8 +158,8 @@ static void bg_init(void)
|
||||
bglobal.bg_mhop = bp_udp_mhop();
|
||||
bglobal.bg_shop6 = bp_udp6_shop();
|
||||
bglobal.bg_mhop6 = bp_udp6_mhop();
|
||||
bglobal.bg_echo = ptm_bfd_echo_sock_init();
|
||||
bglobal.bg_vxlan = ptm_bfd_vxlan_sock_init();
|
||||
bglobal.bg_echo = bp_echo_socket();
|
||||
bglobal.bg_echov6 = bp_echov6_socket();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -216,10 +220,8 @@ int main(int argc, char *argv[])
|
||||
&bglobal.bg_ev[3]);
|
||||
thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo,
|
||||
&bglobal.bg_ev[4]);
|
||||
#if 0 /* TODO VxLAN support. */
|
||||
thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan,
|
||||
thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6,
|
||||
&bglobal.bg_ev[5]);
|
||||
#endif
|
||||
thread_add_read(master, control_accept, NULL, bglobal.bg_csock,
|
||||
&bglobal.bg_csockev);
|
||||
|
||||
|
@ -827,7 +827,7 @@ DEFPY(bfd_show_peers_counters, bfd_show_peers_counters_cmd,
|
||||
* Configuration rules:
|
||||
*
|
||||
* Single hop:
|
||||
* peer + (optional vxlan or interface name)
|
||||
* peer + (interface name)
|
||||
*
|
||||
* Multi hop:
|
||||
* peer + local + (optional vrf)
|
||||
@ -896,23 +896,6 @@ static int bfd_configure_peer(struct bfd_peer_cfg *bpc, bool mhop,
|
||||
|
||||
bpc->bpc_mhop = mhop;
|
||||
|
||||
#if 0
|
||||
/* Handle VxLAN configuration. */
|
||||
if (vxlan >= 0) {
|
||||
if (vxlan > ((1 << 24) - 1)) {
|
||||
snprintf(ebuf, ebuflen, "invalid VxLAN %d", vxlan);
|
||||
return -1;
|
||||
}
|
||||
if (bpc->bpc_mhop) {
|
||||
snprintf(ebuf, ebuflen,
|
||||
"multihop doesn't accept VxLAN");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bpc->bpc_vxlan = vxlan;
|
||||
}
|
||||
#endif /* VxLAN */
|
||||
|
||||
/* Handle interface specification configuration. */
|
||||
if (ifname) {
|
||||
if (bpc->bpc_mhop) {
|
||||
|
178
bfdd/bsd.c
178
bfdd/bsd.c
@ -32,39 +32,9 @@
|
||||
|
||||
#include "bfd.h"
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen);
|
||||
|
||||
/*
|
||||
* Definitions.
|
||||
*/
|
||||
static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen)
|
||||
{
|
||||
const struct sockaddr *sa = sv;
|
||||
const struct sockaddr_in *sin = sv;
|
||||
const struct sockaddr_in6 *sin6 = sv;
|
||||
int unknown = 1;
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
if (inet_ntop(AF_INET, &sin->sin_addr, buf, buflen) != NULL)
|
||||
unknown = 0;
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
if (inet_ntop(AF_INET6, &sin6->sin6_addr, buf, buflen) != NULL)
|
||||
unknown = 0;
|
||||
break;
|
||||
}
|
||||
if (unknown == 0)
|
||||
return buf;
|
||||
|
||||
snprintf(buf, buflen, "unknown (af=%d)", sa->sa_family);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int ptm_bfd_fetch_ifindex(const char *ifname)
|
||||
{
|
||||
return if_nametoindex(ifname);
|
||||
@ -129,133 +99,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen)
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
int ptm_bfd_echo_sock_init(void)
|
||||
{
|
||||
int s, ttl, yes = 1;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
|
||||
if (s == -1) {
|
||||
log_error("echo-socket: creation failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
/* OmniOS doesn't have this field, but uses this code. */
|
||||
sin.sin_len = sizeof(sin);
|
||||
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(3785);
|
||||
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
|
||||
log_error("echo-socket: bind failure: %s", strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(s, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) == -1) {
|
||||
log_error("echo-socket: setsockopt(IP_RECVTTL): %s",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ttl = BFD_TTL_VAL;
|
||||
if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) {
|
||||
log_error("echo-socket: setsockopt(IP_TTL): %s",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen,
|
||||
struct sockaddr_storage *ss, socklen_t *sslen,
|
||||
uint8_t *ttl, uint32_t *id)
|
||||
{
|
||||
struct cmsghdr *cmsg;
|
||||
struct bfd_echo_pkt *bep;
|
||||
ssize_t readlen;
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
uint8_t msgctl[255];
|
||||
char errbuf[255];
|
||||
|
||||
/* Prepare socket read. */
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = *buflen;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = msgctl;
|
||||
msg.msg_controllen = sizeof(msgctl);
|
||||
msg.msg_name = ss;
|
||||
msg.msg_namelen = *sslen;
|
||||
|
||||
/* Read the socket and treat errors. */
|
||||
readlen = recvmsg(sd, &msg, 0);
|
||||
if (readlen == 0) {
|
||||
log_error("%s: recvmsg: socket closed", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (readlen == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
|
||||
return -1;
|
||||
|
||||
log_error("%s: recvmsg: (%d) %s", __func__, errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/* Short packet, better not risk reading it. */
|
||||
if (readlen < (ssize_t)sizeof(*bep)) {
|
||||
log_warning("%s: short packet (%ld of %d) from %s", __func__,
|
||||
readlen, sizeof(*bep),
|
||||
sockaddr_to_string(ss, errbuf, sizeof(errbuf)));
|
||||
return -1;
|
||||
}
|
||||
*buflen = readlen;
|
||||
|
||||
/* Read TTL information. */
|
||||
*ttl = 0;
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level != IPPROTO_IP)
|
||||
continue;
|
||||
if (cmsg->cmsg_type != IP_RECVTTL)
|
||||
continue;
|
||||
|
||||
*ttl = *(uint8_t *)CMSG_DATA(cmsg);
|
||||
break;
|
||||
}
|
||||
if (*ttl == 0) {
|
||||
log_debug("%s: failed to read TTL", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read my discriminator from BFD Echo packet. */
|
||||
bep = (struct bfd_echo_pkt *)buf;
|
||||
*id = bep->my_discr;
|
||||
if (*id == 0) {
|
||||
log_debug("%s: invalid packet discriminator from: %s", __func__,
|
||||
sockaddr_to_string(ss, errbuf, sizeof(errbuf)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the returned sockaddr new length. */
|
||||
*sslen = msg.msg_namelen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ptm_bfd_vxlan_sock_init(void)
|
||||
{
|
||||
/* TODO: not supported yet. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bp_bind_dev(int sd, const char *dev)
|
||||
{
|
||||
/*
|
||||
@ -266,25 +109,4 @@ int bp_bind_dev(int sd, const char *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len)
|
||||
{
|
||||
char *ptr;
|
||||
struct udp_psuedo_header pudp_hdr;
|
||||
uint16_t csum;
|
||||
|
||||
pudp_hdr.saddr = ip->ip_src.s_addr;
|
||||
pudp_hdr.daddr = ip->ip_dst.s_addr;
|
||||
pudp_hdr.reserved = 0;
|
||||
pudp_hdr.protocol = ip->ip_p;
|
||||
pudp_hdr.len = htons(len);
|
||||
|
||||
ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len);
|
||||
memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN);
|
||||
memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len);
|
||||
|
||||
csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len);
|
||||
XFREE(MTYPE_BFDD_TMP, ptr);
|
||||
return csum;
|
||||
}
|
||||
|
||||
#endif /* BFD_BSD */
|
||||
|
@ -218,10 +218,6 @@ static int parse_peer_config(struct json_object *jo, struct bfd_peer_cfg *bpc)
|
||||
} else {
|
||||
log_debug("\tlocal-interface: %s", sval);
|
||||
}
|
||||
} else if (strcmp(key, "vxlan") == 0) {
|
||||
bpc->bpc_vxlan = json_object_get_int64(jo_val);
|
||||
bpc->bpc_has_vxlan = true;
|
||||
log_debug("\tvxlan: %ld", bpc->bpc_vxlan);
|
||||
} else if (strcmp(key, "vrf-name") == 0) {
|
||||
bpc->bpc_has_vrfname = true;
|
||||
sval = json_object_get_string(jo_val);
|
||||
|
36
bfdd/event.c
36
bfdd/event.c
@ -49,8 +49,7 @@ void bfd_recvtimer_update(struct bfd_session *bs)
|
||||
#endif /* BFD_EVENT_DEBUG */
|
||||
|
||||
/* Remove previous schedule if any. */
|
||||
if (bs->recvtimer_ev)
|
||||
bfd_recvtimer_delete(bs);
|
||||
bfd_recvtimer_delete(bs);
|
||||
|
||||
thread_add_timer_tv(master, bfd_recvtimer_cb, bs, &tv,
|
||||
&bs->recvtimer_ev);
|
||||
@ -70,8 +69,7 @@ void bfd_echo_recvtimer_update(struct bfd_session *bs)
|
||||
#endif /* BFD_EVENT_DEBUG */
|
||||
|
||||
/* Remove previous schedule if any. */
|
||||
if (bs->echo_recvtimer_ev)
|
||||
bfd_echo_recvtimer_delete(bs);
|
||||
bfd_echo_recvtimer_delete(bs);
|
||||
|
||||
thread_add_timer_tv(master, bfd_echo_recvtimer_cb, bs, &tv,
|
||||
&bs->echo_recvtimer_ev);
|
||||
@ -91,8 +89,7 @@ void bfd_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
|
||||
#endif /* BFD_EVENT_DEBUG */
|
||||
|
||||
/* Remove previous schedule if any. */
|
||||
if (bs->xmttimer_ev)
|
||||
bfd_xmttimer_delete(bs);
|
||||
bfd_xmttimer_delete(bs);
|
||||
|
||||
thread_add_timer_tv(master, bfd_xmt_cb, bs, &tv, &bs->xmttimer_ev);
|
||||
}
|
||||
@ -111,8 +108,7 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
|
||||
#endif /* BFD_EVENT_DEBUG */
|
||||
|
||||
/* Remove previous schedule if any. */
|
||||
if (bs->echo_xmttimer_ev)
|
||||
bfd_echo_xmttimer_delete(bs);
|
||||
bfd_echo_xmttimer_delete(bs);
|
||||
|
||||
thread_add_timer_tv(master, bfd_echo_xmt_cb, bs, &tv,
|
||||
&bs->echo_xmttimer_ev);
|
||||
@ -120,36 +116,20 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
|
||||
|
||||
void bfd_recvtimer_delete(struct bfd_session *bs)
|
||||
{
|
||||
if (bs->recvtimer_ev == NULL)
|
||||
return;
|
||||
|
||||
thread_cancel(bs->recvtimer_ev);
|
||||
bs->recvtimer_ev = NULL;
|
||||
THREAD_OFF(bs->recvtimer_ev);
|
||||
}
|
||||
|
||||
void bfd_echo_recvtimer_delete(struct bfd_session *bs)
|
||||
{
|
||||
if (bs->echo_recvtimer_ev == NULL)
|
||||
return;
|
||||
|
||||
thread_cancel(bs->echo_recvtimer_ev);
|
||||
bs->echo_recvtimer_ev = NULL;
|
||||
THREAD_OFF(bs->echo_recvtimer_ev);
|
||||
}
|
||||
|
||||
void bfd_xmttimer_delete(struct bfd_session *bs)
|
||||
{
|
||||
if (bs->xmttimer_ev == NULL)
|
||||
return;
|
||||
|
||||
thread_cancel(bs->xmttimer_ev);
|
||||
bs->xmttimer_ev = NULL;
|
||||
THREAD_OFF(bs->xmttimer_ev);
|
||||
}
|
||||
|
||||
void bfd_echo_xmttimer_delete(struct bfd_session *bs)
|
||||
{
|
||||
if (bs->echo_xmttimer_ev == NULL)
|
||||
return;
|
||||
|
||||
thread_cancel(bs->echo_xmttimer_ev);
|
||||
bs->echo_xmttimer_ev = NULL;
|
||||
THREAD_OFF(bs->echo_xmttimer_ev);
|
||||
}
|
||||
|
111
bfdd/linux.c
111
bfdd/linux.c
@ -23,49 +23,8 @@
|
||||
|
||||
#ifdef BFD_LINUX
|
||||
|
||||
/* XXX: fix compilation error on Ubuntu 16.04 or older. */
|
||||
#ifndef _UAPI_IPV6_H
|
||||
#define _UAPI_IPV6_H
|
||||
#endif /* _UAPI_IPV6_H */
|
||||
|
||||
#include <linux/filter.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "bfd.h"
|
||||
|
||||
/* Berkeley Packet filter code to filter out BFD Echo packets.
|
||||
* tcpdump -dd "(udp dst port 3785)"
|
||||
*/
|
||||
static struct sock_filter bfd_echo_filter[] = {
|
||||
{0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd},
|
||||
{0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011},
|
||||
{0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x00000ec9},
|
||||
{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, 0x00000ec9},
|
||||
{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.
|
||||
@ -128,55 +87,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen)
|
||||
ifr.ifr_name, ifname);
|
||||
}
|
||||
|
||||
int ptm_bfd_echo_sock_init(void)
|
||||
{
|
||||
int s;
|
||||
struct sock_fprog bpf = {.len = sizeof(bfd_echo_filter)
|
||||
/ sizeof(bfd_echo_filter[0]),
|
||||
.filter = bfd_echo_filter};
|
||||
|
||||
s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
|
||||
if (s == -1) {
|
||||
log_error("echo-socket: creation failure: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))
|
||||
== -1) {
|
||||
log_error("echo-socket: setsockopt(SO_ATTACH_FILTER): %s",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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__)))
|
||||
{
|
||||
@ -197,25 +107,4 @@ int bp_bind_dev(int sd __attribute__((__unused__)),
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len)
|
||||
{
|
||||
char *ptr;
|
||||
struct udp_psuedo_header pudp_hdr;
|
||||
uint16_t csum;
|
||||
|
||||
pudp_hdr.saddr = iph->saddr;
|
||||
pudp_hdr.daddr = iph->daddr;
|
||||
pudp_hdr.reserved = 0;
|
||||
pudp_hdr.protocol = iph->protocol;
|
||||
pudp_hdr.len = htons(len);
|
||||
|
||||
ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len);
|
||||
memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN);
|
||||
memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len);
|
||||
|
||||
csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len);
|
||||
XFREE(MTYPE_BFDD_TMP, ptr);
|
||||
return csum;
|
||||
}
|
||||
|
||||
#endif /* BFD_LINUX */
|
||||
|
Loading…
Reference in New Issue
Block a user