Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions zebra/dplane_fpm_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,12 +709,13 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
switch (op) {
case DPLANE_OP_ROUTE_UPDATE:
case DPLANE_OP_ROUTE_DELETE:
rv = netlink_route_multipath(RTM_DELROUTE, ctx, nl_buf,
sizeof(nl_buf), true,
fnc->use_nhg);
rv = netlink_route_multipath_msg_encode(RTM_DELROUTE, ctx,
nl_buf, sizeof(nl_buf),
true, fnc->use_nhg);
if (rv <= 0) {
zlog_err("%s: netlink_route_multipath failed",
__func__);
zlog_err(
"%s: netlink_route_multipath_msg_encode failed",
__func__);
return 0;
}

Expand All @@ -726,12 +727,13 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)

/* FALL THROUGH */
case DPLANE_OP_ROUTE_INSTALL:
rv = netlink_route_multipath(
rv = netlink_route_multipath_msg_encode(
RTM_NEWROUTE, ctx, &nl_buf[nl_buf_len],
sizeof(nl_buf) - nl_buf_len, true, fnc->use_nhg);
if (rv <= 0) {
zlog_err("%s: netlink_route_multipath failed",
__func__);
zlog_err(
"%s: netlink_route_multipath_msg_encode failed",
__func__);
return 0;
}

Expand All @@ -751,21 +753,23 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
break;

case DPLANE_OP_NH_DELETE:
rv = netlink_nexthop_encode(RTM_DELNEXTHOP, ctx, nl_buf,
sizeof(nl_buf));
rv = netlink_nexthop_msg_encode(RTM_DELNEXTHOP, ctx, nl_buf,
sizeof(nl_buf));
if (rv <= 0) {
zlog_err("%s: netlink_nexthop_encode failed", __func__);
zlog_err("%s: netlink_nexthop_msg_encode failed",
__func__);
return 0;
}

nl_buf_len = (size_t)rv;
break;
case DPLANE_OP_NH_INSTALL:
case DPLANE_OP_NH_UPDATE:
rv = netlink_nexthop_encode(RTM_NEWNEXTHOP, ctx, nl_buf,
sizeof(nl_buf));
rv = netlink_nexthop_msg_encode(RTM_NEWNEXTHOP, ctx, nl_buf,
sizeof(nl_buf));
if (rv <= 0) {
zlog_err("%s: netlink_nexthop_encode failed", __func__);
zlog_err("%s: netlink_nexthop_msg_encode failed",
__func__);
return 0;
}

Expand Down
24 changes: 12 additions & 12 deletions zebra/if_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ static int netlink_request_intf_addr(struct nlsock *netlink_cmd, int family,

/* Include filter, if specified. */
if (filter_mask)
addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask);
nl_attr_put32(&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask);

return netlink_request(netlink_cmd, &req);
}
Expand Down Expand Up @@ -903,8 +903,8 @@ int kernel_interface_set_master(struct interface *master,

req.ifa.ifi_index = slave->ifindex;

addattr_l(&req.n, sizeof(req), IFLA_MASTER, &master->ifindex, 4);
addattr_l(&req.n, sizeof(req), IFLA_LINK, &slave->ifindex, 4);
nl_attr_put32(&req.n, sizeof(req), IFLA_MASTER, master->ifindex);
nl_attr_put32(&req.n, sizeof(req), IFLA_LINK, slave->ifindex);

return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
0);
Expand Down Expand Up @@ -942,20 +942,20 @@ static int netlink_address_ctx(const struct zebra_dplane_ctx *ctx)

req.ifa.ifa_index = dplane_ctx_get_ifindex(ctx);

addattr_l(&req.n, sizeof(req), IFA_LOCAL, &p->u.prefix, bytelen);
nl_attr_put(&req.n, sizeof(req), IFA_LOCAL, &p->u.prefix, bytelen);

if (p->family == AF_INET) {
if (dplane_ctx_intf_is_connected(ctx)) {
p = dplane_ctx_get_intf_dest(ctx);
addattr_l(&req.n, sizeof(req), IFA_ADDRESS,
&p->u.prefix, bytelen);
nl_attr_put(&req.n, sizeof(req), IFA_ADDRESS,
&p->u.prefix, bytelen);
} else if (cmd == RTM_NEWADDR) {
struct in_addr broad = {
.s_addr = ipv4_broadcast_addr(p->u.prefix4.s_addr,
p->prefixlen)
};
addattr_l(&req.n, sizeof(req), IFA_BROADCAST,
&broad, bytelen);
nl_attr_put(&req.n, sizeof(req), IFA_BROADCAST, &broad,
bytelen);
}
}

Expand All @@ -967,8 +967,8 @@ static int netlink_address_ctx(const struct zebra_dplane_ctx *ctx)

if (dplane_ctx_intf_has_label(ctx)) {
label = dplane_ctx_get_intf_label(ctx);
addattr_l(&req.n, sizeof(req), IFA_LABEL, label,
strlen(label) + 1);
nl_attr_put(&req.n, sizeof(req), IFA_LABEL, label,
strlen(label) + 1);
}

return netlink_talk_info(netlink_talk_filter, &req.n,
Expand Down Expand Up @@ -1520,8 +1520,8 @@ int netlink_protodown(struct interface *ifp, bool down)

req.ifa.ifi_index = ifp->ifindex;

addattr_l(&req.n, sizeof(req), IFLA_PROTO_DOWN, &down, sizeof(down));
addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifp->ifindex, 4);
nl_attr_put(&req.n, sizeof(req), IFLA_PROTO_DOWN, &down, sizeof(down));
nl_attr_put32(&req.n, sizeof(req), IFLA_LINK, ifp->ifindex);

return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
0);
Expand Down
72 changes: 28 additions & 44 deletions zebra/kernel_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,16 +527,16 @@ void netlink_parse_rtattr_nested(struct rtattr **tb, int max,
netlink_parse_rtattr(tb, max, RTA_DATA(rta), RTA_PAYLOAD(rta));
}

int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type,
const void *data, unsigned int alen)
bool nl_attr_put(struct nlmsghdr *n, unsigned int maxlen, int type,
const void *data, unsigned int alen)
{
int len;
struct rtattr *rta;

len = RTA_LENGTH(alen);

if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
return -1;
return false;

rta = (struct rtattr *)(((char *)n) + NLMSG_ALIGN(n->nlmsg_len));
rta->rta_type = type;
Expand All @@ -549,72 +549,56 @@ int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type,

n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);

return 0;
}

int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type,
const void *data, unsigned int alen)
{
unsigned int len;
struct rtattr *subrta;

len = RTA_LENGTH(alen);

if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen)
return -1;

subrta = (struct rtattr *)(((char *)rta) + RTA_ALIGN(rta->rta_len));
subrta->rta_type = type;
subrta->rta_len = len;

if (data)
memcpy(RTA_DATA(subrta), data, alen);
else
assert(alen == 0);

rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len);

return 0;
return true;
}

int addattr16(struct nlmsghdr *n, unsigned int maxlen, int type, uint16_t data)
bool nl_attr_put16(struct nlmsghdr *n, unsigned int maxlen, int type,
uint16_t data)
{
return addattr_l(n, maxlen, type, &data, sizeof(uint16_t));
return nl_attr_put(n, maxlen, type, &data, sizeof(uint16_t));
}

int addattr32(struct nlmsghdr *n, unsigned int maxlen, int type, int data)
bool nl_attr_put32(struct nlmsghdr *n, unsigned int maxlen, int type,
uint32_t data)
{
return addattr_l(n, maxlen, type, &data, sizeof(uint32_t));
return nl_attr_put(n, maxlen, type, &data, sizeof(uint32_t));
}

struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type)
struct rtattr *nl_attr_nest(struct nlmsghdr *n, unsigned int maxlen, int type)
{
struct rtattr *nest = NLMSG_TAIL(n);

addattr_l(n, maxlen, type, NULL, 0);
if (!nl_attr_put(n, maxlen, type, NULL, 0))
return NULL;

nest->rta_type |= NLA_F_NESTED;
return nest;
}

int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest)
int nl_attr_nest_end(struct nlmsghdr *n, struct rtattr *nest)
{
nest->rta_len = (uint8_t *)NLMSG_TAIL(n) - (uint8_t *)nest;
return n->nlmsg_len;
}

struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type)
struct rtnexthop *nl_attr_rtnh(struct nlmsghdr *n, unsigned int maxlen)
{
struct rtattr *nest = RTA_TAIL(rta);
struct rtnexthop *rtnh = (struct rtnexthop *)NLMSG_TAIL(n);

rta_addattr_l(rta, maxlen, type, NULL, 0);
nest->rta_type |= NLA_F_NESTED;
return nest;
if (NLMSG_ALIGN(n->nlmsg_len) + RTNH_ALIGN(sizeof(struct rtnexthop))
> maxlen)
return NULL;

memset(rtnh, 0, sizeof(struct rtnexthop));
n->nlmsg_len =
NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(sizeof(struct rtnexthop));

return rtnh;
}

int rta_nest_end(struct rtattr *rta, struct rtattr *nest)
void nl_attr_rtnh_end(struct nlmsghdr *n, struct rtnexthop *rtnh)
{
nest->rta_len = (uint8_t *)RTA_TAIL(rta) - (uint8_t *)nest;
return rta->rta_len;
rtnh->rtnh_len = (uint8_t *)NLMSG_TAIL(n) - (uint8_t *)rtnh;
}

const char *nl_msg_type_to_str(uint16_t msg_type)
Expand Down
59 changes: 47 additions & 12 deletions zebra/kernel_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,57 @@ extern "C" {
#define NL_RCV_PKT_BUF_SIZE 32768
#define NL_PKT_BUF_SIZE 8192

/*
* nl_attr_put - add an attribute to the Netlink message.
*
* Returns true if the attribute could be added to the message (fits into the
* buffer), otherwise false is returned.
*/
extern bool nl_attr_put(struct nlmsghdr *n, unsigned int maxlen, int type,
const void *data, unsigned int alen);
extern bool nl_attr_put16(struct nlmsghdr *n, unsigned int maxlen, int type,
uint16_t data);
extern bool nl_attr_put32(struct nlmsghdr *n, unsigned int maxlen, int type,
uint32_t data);

/*
* nl_attr_nest - start an attribute nest.
*
* Returns a valid pointer to the beginning of the nest if the attribute
* describing the nest could be added to the message (fits into the buffer),
* otherwise NULL is returned.
*/
extern struct rtattr *nl_attr_nest(struct nlmsghdr *n, unsigned int maxlen,
int type);

/*
* nl_attr_nest_end - finalize nesting of attributes.
*
* Updates the length field of the attribute header to include the appeneded
* attributes. Returns a total length of the Netlink message.
*/
extern int nl_attr_nest_end(struct nlmsghdr *n, struct rtattr *nest);

/*
* nl_attr_rtnh - append a rtnexthop record to the Netlink message.
*
* Returns a valid pointer to the rtnexthop struct if it could be added to
* the message (fits into the buffer), otherwise NULL is returned.
*/
extern struct rtnexthop *nl_attr_rtnh(struct nlmsghdr *n, unsigned int maxlen);

/*
* nl_attr_rtnh_end - finalize adding a rtnexthop record.
*
* Updates the length field of the rtnexthop to include the appeneded
* attributes.
*/
extern void nl_attr_rtnh_end(struct nlmsghdr *n, struct rtnexthop *rtnh);

extern void netlink_parse_rtattr(struct rtattr **tb, int max,
struct rtattr *rta, int len);
extern void netlink_parse_rtattr_nested(struct rtattr **tb, int max,
struct rtattr *rta);
extern int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type,
const void *data, unsigned int alen);
extern int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type,
const void *data, unsigned int alen);
extern int addattr16(struct nlmsghdr *n, unsigned int maxlen, int type,
uint16_t data);
extern int addattr32(struct nlmsghdr *n, unsigned int maxlen, int type,
int data);
extern struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type);
extern int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest);
extern struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type);
extern int rta_nest_end(struct rtattr *rta, struct rtattr *nest);
extern const char *nl_msg_type_to_str(uint16_t msg_type);
extern const char *nl_rtproto_to_str(uint8_t rtproto);
extern const char *nl_family_to_str(uint8_t family);
Expand Down
Loading