Skip to content

Commit

Permalink
lldpad: Introduce support for multiple agents per port
Browse files Browse the repository at this point in the history
This patch introduces support for multiple agents per port.
Each agent sends and receives frames to and from different group mac
addresses. Right now these are nearest bridge, nearest customer bridge and
nearest non-twoport mac-relaying bridge.

It splits out most of the agent specific variables from the port structure
to an agent structure. This requires changes in the rx and tx state
machines.

With the changes for the multi-agent support, adminStatus has moved from the
port to the agent. As port->adminStatus has been used to control the VDP
state machines as well, a new mechanism was needed here.
The VDP module does not have agent support, so port->adminStatus is replaced
by the vdp->enableTx flag. If this is set to yes by lldptool, VDP will be
active, and will be inactive if set to no.

JF: fixed some minor nit issues and a few real bugs as well as
    some style items.

Signed-off-by: Jens Osterkamp <[email protected]>
Signed-off-by: John Fastabend <[email protected]>
  • Loading branch information
Jens Osterkamp authored and John Fastabend committed Oct 5, 2011
1 parent dd9d2a3 commit 99fedf7
Show file tree
Hide file tree
Showing 45 changed files with 1,416 additions and 1,010 deletions.
116 changes: 102 additions & 14 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
#include "eloop.h"
#include "lldpad.h"
#include "lldp.h"
#include "lldp/ports.h"
#include "lldp/agent.h"
#include "lldp/l2_packet.h"
#include "lldp_util.h"
#include "lldp_mod.h"
#include "lldp_mand_clif.h"
Expand All @@ -47,7 +50,6 @@
#include "messages.h"
#include "config.h"
#include "clif_msgs.h"
#include "lldp/l2_packet.h"
#include "lldp_mod.h"
#include "event_iface.h"

Expand Down Expand Up @@ -149,21 +151,28 @@ void scan_port(void *eloop_data, void *user_ctx)
* IF_OPER_UP, IF_OPER_DOWN or IF_OPER_DORMANT.
*/
p = nameidx;
port = porthead;
while (p->if_index != 0) {
struct lldp_module *np;
const struct lldp_mod_ops *ops;
char *ifname = p->if_name;
struct lldp_agent *agent;

if (is_valid_lldp_device(ifname)) {
if (check_link_status(ifname))
oper_add_device(ifname);
else {
LIST_FOREACH(np, &lldp_head, lldp) {
ops = np->ops;
if (ops->lldp_mod_ifdown)
ops->lldp_mod_ifdown(ifname);

LIST_FOREACH(agent, &port->agent_head, entry) {
LLDPAD_DBG("%s: calling ifdown for agent %p.\n",
__func__, agent);
LIST_FOREACH(np, &lldp_head, lldp) {
ops = np->ops;
if (ops->lldp_mod_ifdown)
ops->lldp_mod_ifdown(ifname, agent);
}
}
set_lldp_port_enable_state(ifname, 0);
set_lldp_port_enable(ifname, 0);
}
}
p++;
Expand Down Expand Up @@ -337,6 +346,8 @@ void init_ports(void)
{
struct lldp_module *np;
struct if_nameindex *nameidx, *p;
struct port *port;
struct lldp_agent *agent;

nameidx = if_nameindex();
if (nameidx == NULL) {
Expand All @@ -347,27 +358,34 @@ void init_ports(void)
p = nameidx;
while (p->if_index != 0) {
int valid = is_valid_lldp_device(p->if_name);
int err;

if (!valid) {
p++;
continue;
}

if (is_bond(p->if_name))
err = add_bond_port(p->if_name);
port = add_bond_port(p->if_name);
else
err = add_port(p->if_name);
port = add_port(p->if_name);

if (err) {
if (port == NULL) {
LLDPAD_ERR("%s: Error adding device %s\n",
__func__, p->if_name);
} else if (check_link_status(p->if_name)) {
LIST_FOREACH(np, &lldp_head, lldp) {
if (np->ops->lldp_mod_ifup)
np->ops->lldp_mod_ifup(p->if_name);
lldp_add_agent(p->if_name, NEAREST_BRIDGE);
lldp_add_agent(p->if_name, NEAREST_NONTPMR_BRIDGE);
lldp_add_agent(p->if_name, NEAREST_CUSTOMER_BRIDGE);

LIST_FOREACH(agent, &port->agent_head, entry) {
LLDPAD_DBG("%s: calling ifup for agent %p.\n",
__func__, agent);
LIST_FOREACH(np, &lldp_head, lldp) {
if (np->ops->lldp_mod_ifup)
np->ops->lldp_mod_ifup(p->if_name, agent);
}
}
set_lldp_port_enable_state(p->if_name, 1);
set_lldp_port_enable(p->if_name, 1);
}
p++;
}
Expand Down Expand Up @@ -413,6 +431,76 @@ static int lookup_config_value(char *path, void *value, int type)
}
}


/*
* get_config_setting_by_agent - get the setting from the given config file path by type
* @ifname: interface name
* @agenttype: type of agent this needs to be retrieved from
* @path: relative to LLDP_COMMON or ifname section of LLDP configuration.
* @value: pointer to the value to be retrieved
* @type: libconfig value types
*
* Returns cmd_success(0) for success, otherwise for failure.
*
* This function assumes init_cfg() has been called.
*/
int get_config_setting_by_agent(const char *ifname, int agenttype, char *path,
void *value, int type)
{
char p[1024];
int rval = CONFIG_FALSE;

/* look for setting in ifname areas first */
if (ifname) {
switch(agenttype) {
case NEAREST_BRIDGE:
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_SETTING, ifname, path);
rval = lookup_config_value(p, value, type);
if (rval == CONFIG_FALSE) {
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_NB, ifname, path);
}
break;
case NEAREST_CUSTOMER_BRIDGE:
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_NCB, ifname, path);
break;
case NEAREST_NONTPMR_BRIDGE:
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_NNTPB, ifname, path);
break;
}
rval = lookup_config_value(p, value, type);
}

/* if not found look for setting in common area */
if (rval == CONFIG_FALSE) {
switch(agenttype) {
case NEAREST_BRIDGE:
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_SETTING, LLDP_COMMON, path);
rval = lookup_config_value(p, value, type);
if (rval == CONFIG_FALSE) {
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_NB, LLDP_COMMON, path);
}
break;
case NEAREST_CUSTOMER_BRIDGE:
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_NCB, LLDP_COMMON, path);
break;
case NEAREST_NONTPMR_BRIDGE:
snprintf(p, sizeof(p), "%s.%s.%s",
LLDP_NNTPB, LLDP_COMMON, path);
break;
}
rval = lookup_config_value(p, value, type);
}

return (rval == CONFIG_FALSE) ? cmd_failed : cmd_success;
}

/*
* get_config_setting - get the setting from the given config file path by type
* @ifname: interface name
Expand Down
9 changes: 3 additions & 6 deletions dcb_protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,6 @@ void features_erase(features_it *p)
*p = NULL;
}

int add_port(const char *device_name);
int remove_port(const char *device_name);

/* Add the store pointer to init_pg, i.e. memset store to 0,
* then copy attribs to store
*/
Expand Down Expand Up @@ -3772,7 +3769,7 @@ dcb_result run_control_protocol(char *device_name, u32 EventFlag)
ctrl_prot->second->AckNo);

/* Send new DCB ctrl & feature TLVs */
somethingChangedLocal(device_name);
somethingChangedLocal(device_name, NEAREST_BRIDGE);
}
}
return dcb_success;
Expand Down Expand Up @@ -3887,7 +3884,7 @@ dcb_result run_control_protocol(char *device_name, u32 EventFlag)
ctrl_prot->second->SeqNo,
ctrl_prot->second->AckNo);
/* Send new DCB control & feature TLVs*/
somethingChangedLocal(device_name);
somethingChangedLocal(device_name, NEAREST_BRIDGE);
return dcb_success;
}

Expand All @@ -3900,7 +3897,7 @@ dcb_result run_control_protocol(char *device_name, u32 EventFlag)
ctrl_prot->second->SeqNo,
ctrl_prot->second->AckNo);
/* Send new DCB TLVs with old feature TLVs. */
somethingChangedLocal(device_name);
somethingChangedLocal(device_name, NEAREST_BRIDGE);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions ecp/ecp.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ struct ecp {
int ackTimer;
u16 lastSequence;
u16 seqECPDU;
struct portrx rx;
struct porttx tx;
struct portstats stats;
struct agentrx rx;
struct agenttx tx;
struct agentstats stats;
};

struct ecp_hdr {
Expand Down
5 changes: 4 additions & 1 deletion ecp/ecp_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ void ecp_rx_ReceiveFrame(void *ctx, unsigned int ifindex, const u8 *buf, size_t

port = port_find_by_name(vd->ifname);

if (port == NULL)
return;

LLDPAD_DBG("%s(%i)-%s: received packet with size %i\n", __func__, __LINE__,
vd->ifname, (int) len);

Expand All @@ -234,7 +237,7 @@ void ecp_rx_ReceiveFrame(void *ctx, unsigned int ifindex, const u8 *buf, size_t

vd->ecp.rx.sizein = (u16)len;
ex = &example_hdr;
memcpy(ex->h_dest, multi_cast_source, ETH_ALEN);
memcpy(ex->h_dest, nearest_bridge, ETH_ALEN);
ex->h_proto = htons(ETH_P_ECP);
hdr = (struct l2_ethhdr *)vd->ecp.rx.framein;

Expand Down
7 changes: 3 additions & 4 deletions ecp/ecp_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,8 @@ bool ecp_build_ECPDU(struct vdp_data *vd)
struct packed_tlv *ptlv = NULL;
struct vsi_profile *p;

/* TODO: different multicast address for sending ECP over S-channel (multi_cast_source_s)
* S-channels to implement later */
memcpy(eth.h_dest, multi_cast_source, ETH_ALEN);
/* TODO: use LLDP group MAC addresses to support S-channels/multichannel*/
memcpy(eth.h_dest, nearest_bridge, ETH_ALEN);
l2_packet_get_own_src_addr(vd->ecp.l2,(u8 *)&own_addr);
memcpy(eth.h_source, &own_addr, ETH_ALEN);
eth.h_proto = htons(ETH_P_ECP);
Expand Down Expand Up @@ -267,7 +266,7 @@ u8 ecp_txFrame(struct vdp_data *vd)
{
int status = 0;

status = l2_packet_send(vd->ecp.l2, (u8 *)&multi_cast_source,
status = l2_packet_send(vd->ecp.l2, (u8 *)&nearest_bridge,
htons(ETH_P_ECP),vd->ecp.tx.frameout,vd->ecp.tx.sizeout);
vd->ecp.stats.statsFramesOutTotal++;

Expand Down
54 changes: 36 additions & 18 deletions event_iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ static void event_if_decode_rta(int type, struct rtattr *rta, int *ls, char *d)
int oper_add_device(char *device_name)
{
struct lldp_module *np;
const struct lldp_mod_ops *ops;
struct port *port;
struct port *port, *newport;
struct lldp_agent *agent;
int err;

port = porthead;
Expand All @@ -202,27 +202,35 @@ int oper_add_device(char *device_name)

if (!port) {
if (is_bond(device_name))
err = add_bond_port(device_name);
newport = add_bond_port(device_name);
else
err = add_port(device_name);
newport = add_port(device_name);

if (err) {
if (newport == NULL) {
LLDPAD_INFO("%s: Error adding device %s\n",
__func__, device_name);
return err;
} else
LLDPAD_INFO("%s: Adding device %s\n",
__func__, device_name);
}

LLDPAD_INFO("%s: Adding device %s\n", __func__, device_name);
port = newport;
} else if (!port->portEnabled)
reinit_port(device_name);

LIST_FOREACH(np, &lldp_head, lldp) {
ops = np->ops;
if (ops->lldp_mod_ifup)
ops->lldp_mod_ifup(device_name);
lldp_add_agent(device_name, NEAREST_BRIDGE);
lldp_add_agent(device_name, NEAREST_NONTPMR_BRIDGE);
lldp_add_agent(device_name, NEAREST_CUSTOMER_BRIDGE);

LIST_FOREACH(agent, &port->agent_head, entry) {
LLDPAD_DBG("%s: calling ifup for agent %p.\n",
__func__, agent);
LIST_FOREACH(np, &lldp_head, lldp) {
if (np->ops->lldp_mod_ifup)
np->ops->lldp_mod_ifup(device_name, agent);
}
}

set_lldp_port_enable_state(device_name, 1);
set_lldp_port_enable(device_name, 1);
return 0;
}

Expand All @@ -232,6 +240,7 @@ static void event_if_decode_nlmsg(int route_type, void *data, int len)
const struct lldp_mod_ops *ops;
struct rtattr *rta;
char device_name[IFNAMSIZ];
struct lldp_agent *agent;
int attrlen;
int valid;
int link_status = IF_OPER_UNKNOWN;
Expand Down Expand Up @@ -274,14 +283,23 @@ static void event_if_decode_nlmsg(int route_type, void *data, int len)
if (!valid)
break;

LIST_FOREACH(np, &lldp_head, lldp) {
ops = np->ops;
if (ops->lldp_mod_ifdown)
ops->lldp_mod_ifdown(device_name);
struct port *port = port_find_by_name(device_name);
if (!port)
break;

LIST_FOREACH(agent, &port->agent_head, entry) {
LLDPAD_DBG("%s: calling ifdown for agent %p.\n",
__func__, agent);
LIST_FOREACH(np, &lldp_head, lldp) {
ops = np->ops;
if (ops->lldp_mod_ifdown)
ops->lldp_mod_ifdown(device_name,
agent);
}
}

/* Disable Port */
set_lldp_port_enable_state(device_name, 0);
set_lldp_port_enable(device_name, 0);

if (route_type == RTM_DELLINK) {
LLDPAD_INFO("%s: %s: device removed!\n",
Expand Down
2 changes: 2 additions & 0 deletions include/clif_msgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct cmd {
__u32 module_id;
__u32 ops;
__u32 tlvid;
__u8 type;
char ifname[IFNAMSIZ+1];
char obuf[MAX_CLIF_MSGBUF];
};
Expand All @@ -117,6 +118,7 @@ typedef enum {
cmd_success = 0,
cmd_failed,
cmd_device_not_found,
cmd_agent_not_found,
cmd_invalid,
cmd_bad_params,
cmd_peer_not_present,
Expand Down
Loading

0 comments on commit 99fedf7

Please sign in to comment.