Skip to content

Commit

Permalink
Merge pull request #3786 from mjstapp/dplane_intf
Browse files Browse the repository at this point in the history
zebra: async interface address programming
  • Loading branch information
donaldsharp committed Apr 22, 2019
2 parents 0b4f815 + 39fa282 commit 8f19bc1
Show file tree
Hide file tree
Showing 10 changed files with 576 additions and 195 deletions.
20 changes: 10 additions & 10 deletions lib/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,21 +436,21 @@ void if_set_index(struct interface *ifp, ifindex_t ifindex)
}

/* Does interface up ? */
int if_is_up(struct interface *ifp)
int if_is_up(const struct interface *ifp)
{
return ifp->flags & IFF_UP;
}

/* Is interface running? */
int if_is_running(struct interface *ifp)
int if_is_running(const struct interface *ifp)
{
return ifp->flags & IFF_RUNNING;
}

/* Is the interface operative, eg. either UP & RUNNING
or UP & !ZEBRA_INTERFACE_LINK_DETECTION and
if ptm checking is enabled, then ptm check has passed */
int if_is_operative(struct interface *ifp)
int if_is_operative(const struct interface *ifp)
{
return ((ifp->flags & IFF_UP)
&& (((ifp->flags & IFF_RUNNING)
Expand All @@ -461,7 +461,7 @@ int if_is_operative(struct interface *ifp)

/* Is the interface operative, eg. either UP & RUNNING
or UP & !ZEBRA_INTERFACE_LINK_DETECTION, without PTM check */
int if_is_no_ptm_operative(struct interface *ifp)
int if_is_no_ptm_operative(const struct interface *ifp)
{
return ((ifp->flags & IFF_UP)
&& ((ifp->flags & IFF_RUNNING)
Expand All @@ -470,7 +470,7 @@ int if_is_no_ptm_operative(struct interface *ifp)
}

/* Is this loopback interface ? */
int if_is_loopback(struct interface *ifp)
int if_is_loopback(const struct interface *ifp)
{
/* XXX: Do this better, eg what if IFF_WHATEVER means X on platform M
* but Y on platform N?
Expand All @@ -479,12 +479,12 @@ int if_is_loopback(struct interface *ifp)
}

/* Check interface is VRF */
int if_is_vrf(struct interface *ifp)
int if_is_vrf(const struct interface *ifp)
{
return CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
}

bool if_is_loopback_or_vrf(struct interface *ifp)
bool if_is_loopback_or_vrf(const struct interface *ifp)
{
if (if_is_loopback(ifp) || if_is_vrf(ifp))
return true;
Expand All @@ -493,19 +493,19 @@ bool if_is_loopback_or_vrf(struct interface *ifp)
}

/* Does this interface support broadcast ? */
int if_is_broadcast(struct interface *ifp)
int if_is_broadcast(const struct interface *ifp)
{
return ifp->flags & IFF_BROADCAST;
}

/* Does this interface support broadcast ? */
int if_is_pointopoint(struct interface *ifp)
int if_is_pointopoint(const struct interface *ifp)
{
return ifp->flags & IFF_POINTOPOINT;
}

/* Does this interface support multicast ? */
int if_is_multicast(struct interface *ifp)
int if_is_multicast(const struct interface *ifp)
{
return ifp->flags & IFF_MULTICAST;
}
Expand Down
20 changes: 10 additions & 10 deletions lib/if.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,16 +499,16 @@ extern void if_delete_retain(struct interface *);
deletes it from the interface list and frees the structure. */
extern void if_delete(struct interface *);

extern int if_is_up(struct interface *);
extern int if_is_running(struct interface *);
extern int if_is_operative(struct interface *);
extern int if_is_no_ptm_operative(struct interface *);
extern int if_is_loopback(struct interface *);
extern int if_is_vrf(struct interface *ifp);
extern bool if_is_loopback_or_vrf(struct interface *ifp);
extern int if_is_broadcast(struct interface *);
extern int if_is_pointopoint(struct interface *);
extern int if_is_multicast(struct interface *);
extern int if_is_up(const struct interface *ifp);
extern int if_is_running(const struct interface *ifp);
extern int if_is_operative(const struct interface *ifp);
extern int if_is_no_ptm_operative(const struct interface *ifp);
extern int if_is_loopback(const struct interface *ifp);
extern int if_is_vrf(const struct interface *ifp);
extern bool if_is_loopback_or_vrf(const struct interface *ifp);
extern int if_is_broadcast(const struct interface *ifp);
extern int if_is_pointopoint(const struct interface *ifp);
extern int if_is_multicast(const struct interface *ifp);
struct vrf;
extern void if_terminate(struct vrf *vrf);
extern void if_dump_all(void);
Expand Down
86 changes: 37 additions & 49 deletions zebra/if_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -839,84 +839,72 @@ int kernel_interface_set_master(struct interface *master,
}

/* Interface address modification. */
static int netlink_address(int cmd, int family, struct interface *ifp,
struct connected *ifc)
static int netlink_address_ctx(const struct zebra_dplane_ctx *ctx)
{
int bytelen;
struct prefix *p;
const struct prefix *p;
int cmd;
const char *label;

struct {
struct nlmsghdr n;
struct ifaddrmsg ifa;
char buf[NL_PKT_BUF_SIZE];
} req;

struct zebra_ns *zns;

if (vrf_is_backend_netns())
zns = zebra_ns_lookup((ns_id_t)ifp->vrf_id);
else
zns = zebra_ns_lookup(NS_DEFAULT);
p = ifc->address;
memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE);
p = dplane_ctx_get_intf_addr(ctx);
memset(&req, 0, sizeof(req) - NL_PKT_BUF_SIZE);

bytelen = (family == AF_INET ? 4 : 16);
bytelen = (p->family == AF_INET ? 4 : 16);

req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = cmd;
req.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid;

req.ifa.ifa_family = family;
if (dplane_ctx_get_op(ctx) == DPLANE_OP_ADDR_INSTALL)
cmd = RTM_NEWADDR;
else
cmd = RTM_DELADDR;

req.n.nlmsg_type = cmd;
req.ifa.ifa_family = p->family;

req.ifa.ifa_index = ifp->ifindex;
req.ifa.ifa_index = dplane_ctx_get_ifindex(ctx);

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

if (family == AF_INET) {
if (CONNECTED_PEER(ifc)) {
p = ifc->destination;
addattr_l(&req.n, sizeof req, IFA_ADDRESS, &p->u.prefix,
bytelen);
} else if (cmd == RTM_NEWADDR && ifc->destination) {
p = ifc->destination;
addattr_l(&req.n, sizeof req, IFA_BROADCAST,
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);
} else if (cmd == RTM_NEWADDR &&
dplane_ctx_intf_has_dest(ctx)) {
p = dplane_ctx_get_intf_dest(ctx);
addattr_l(&req.n, sizeof(req), IFA_BROADCAST,
&p->u.prefix, bytelen);
}
}

/* p is now either ifc->address or ifc->destination */
/* p is now either address or destination/bcast addr */
req.ifa.ifa_prefixlen = p->prefixlen;

if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
if (dplane_ctx_intf_is_secondary(ctx))
SET_FLAG(req.ifa.ifa_flags, IFA_F_SECONDARY);

if (ifc->label)
addattr_l(&req.n, sizeof req, IFA_LABEL, ifc->label,
strlen(ifc->label) + 1);

return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
0);
}

int kernel_address_add_ipv4(struct interface *ifp, struct connected *ifc)
{
return netlink_address(RTM_NEWADDR, AF_INET, ifp, ifc);
}

int kernel_address_delete_ipv4(struct interface *ifp, struct connected *ifc)
{
return netlink_address(RTM_DELADDR, AF_INET, ifp, ifc);
}
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);
}

int kernel_address_add_ipv6(struct interface *ifp, struct connected *ifc)
{
return netlink_address(RTM_NEWADDR, AF_INET6, ifp, ifc);
return netlink_talk_info(netlink_talk_filter, &req.n,
dplane_ctx_get_ns(ctx), 0);
}

int kernel_address_delete_ipv6(struct interface *ifp, struct connected *ifc)
enum zebra_dplane_result kernel_address_update_ctx(struct zebra_dplane_ctx *ctx)
{
return netlink_address(RTM_DELADDR, AF_INET6, ifp, ifc);
return (netlink_address_ctx(ctx) == 0 ?
ZEBRA_DPLANE_REQUEST_SUCCESS : ZEBRA_DPLANE_REQUEST_FAILURE);
}

int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
Expand Down
46 changes: 26 additions & 20 deletions zebra/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ static void if_addr_wakeup(struct interface *ifp)
struct listnode *node, *nnode;
struct connected *ifc;
struct prefix *p;
int ret;
enum zebra_dplane_result dplane_res;

for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) {
p = ifc->address;
Expand Down Expand Up @@ -479,12 +479,13 @@ static void if_addr_wakeup(struct interface *ifp)
if_refresh(ifp);
}

ret = if_set_prefix(ifp, ifc);
if (ret < 0) {
dplane_res = dplane_intf_addr_set(ifp, ifc);
if (dplane_res ==
ZEBRA_DPLANE_REQUEST_FAILURE) {
flog_err_sys(
EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
"Can't set interface's address: %s",
safe_strerror(errno));
dplane_res2str(dplane_res));
continue;
}

Expand All @@ -502,12 +503,14 @@ static void if_addr_wakeup(struct interface *ifp)
if_refresh(ifp);
}

ret = if_prefix_add_ipv6(ifp, ifc);
if (ret < 0) {

dplane_res = dplane_intf_addr_set(ifp, ifc);
if (dplane_res ==
ZEBRA_DPLANE_REQUEST_FAILURE) {
flog_err_sys(
EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
"Can't set interface's address: %s",
safe_strerror(errno));
dplane_res2str(dplane_res));
continue;
}

Expand Down Expand Up @@ -2629,6 +2632,7 @@ static int ip_address_install(struct vty *vty, struct interface *ifp,
struct connected *ifc;
struct prefix_ipv4 *p;
int ret;
enum zebra_dplane_result dplane_res;

if_data = ifp->info;

Expand Down Expand Up @@ -2702,10 +2706,10 @@ static int ip_address_install(struct vty *vty, struct interface *ifp,
if_refresh(ifp);
}

ret = if_set_prefix(ifp, ifc);
if (ret < 0) {
dplane_res = dplane_intf_addr_set(ifp, ifc);
if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
vty_out(vty, "%% Can't set interface IP address: %s.\n",
safe_strerror(errno));
dplane_res2str(dplane_res));
return CMD_WARNING_CONFIG_FAILED;
}

Expand All @@ -2726,6 +2730,7 @@ static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
struct prefix_ipv4 lp, pp;
struct connected *ifc;
int ret;
enum zebra_dplane_result dplane_res;

/* Convert to prefix structure. */
ret = str2prefix_ipv4(addr_str, &lp);
Expand Down Expand Up @@ -2770,10 +2775,10 @@ static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
}

/* This is real route. */
ret = if_unset_prefix(ifp, ifc);
if (ret < 0) {
dplane_res = dplane_intf_addr_unset(ifp, ifc);
if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
vty_out(vty, "%% Can't unset interface IP address: %s.\n",
safe_strerror(errno));
dplane_res2str(dplane_res));
return CMD_WARNING_CONFIG_FAILED;
}
UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
Expand Down Expand Up @@ -2880,6 +2885,7 @@ static int ipv6_address_install(struct vty *vty, struct interface *ifp,
struct connected *ifc;
struct prefix_ipv6 *p;
int ret;
enum zebra_dplane_result dplane_res;

if_data = ifp->info;

Expand Down Expand Up @@ -2926,11 +2932,10 @@ static int ipv6_address_install(struct vty *vty, struct interface *ifp,
if_refresh(ifp);
}

ret = if_prefix_add_ipv6(ifp, ifc);

if (ret < 0) {
dplane_res = dplane_intf_addr_set(ifp, ifc);
if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
vty_out(vty, "%% Can't set interface IP address: %s.\n",
safe_strerror(errno));
dplane_res2str(dplane_res));
return CMD_WARNING_CONFIG_FAILED;
}

Expand Down Expand Up @@ -2964,6 +2969,7 @@ static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
struct prefix_ipv6 cp;
struct connected *ifc;
int ret;
enum zebra_dplane_result dplane_res;

/* Convert to prefix structure. */
ret = str2prefix_ipv6(addr_str, &cp);
Expand Down Expand Up @@ -2994,10 +3000,10 @@ static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
}

/* This is real route. */
ret = if_prefix_delete_ipv6(ifp, ifc);
if (ret < 0) {
dplane_res = dplane_intf_addr_unset(ifp, ifc);
if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
vty_out(vty, "%% Can't unset interface IP address: %s.\n",
safe_strerror(errno));
dplane_res2str(dplane_res));
return CMD_WARNING_CONFIG_FAILED;
}

Expand Down
Loading

0 comments on commit 8f19bc1

Please sign in to comment.