dhcpmon: support dual tor scenario (#7471)
This commit is contained in:
parent
d76206bae4
commit
1c2c1f50ba
@ -130,7 +130,7 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context,
|
|||||||
case DHCP_MESSAGE_TYPE_INFORM:
|
case DHCP_MESSAGE_TYPE_INFORM:
|
||||||
giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 |
|
giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 |
|
||||||
dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]);
|
dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]);
|
||||||
if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) ||
|
if ((context->giaddr_ip == giaddr && context->is_uplink && dir == DHCP_TX) ||
|
||||||
(!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) {
|
(!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) {
|
||||||
context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
||||||
aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
||||||
@ -140,7 +140,7 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context,
|
|||||||
case DHCP_MESSAGE_TYPE_OFFER:
|
case DHCP_MESSAGE_TYPE_OFFER:
|
||||||
case DHCP_MESSAGE_TYPE_ACK:
|
case DHCP_MESSAGE_TYPE_ACK:
|
||||||
case DHCP_MESSAGE_TYPE_NAK:
|
case DHCP_MESSAGE_TYPE_NAK:
|
||||||
if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) ||
|
if ((context->giaddr_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) ||
|
||||||
(!context->is_uplink && dir == DHCP_TX)) {
|
(!context->is_uplink && dir == DHCP_TX)) {
|
||||||
context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
||||||
aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
|
||||||
@ -438,7 +438,7 @@ static int init_socket(dhcp_device_context_t *context, const char *intf)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise for failure
|
* @return 0 on success, otherwise for failure
|
||||||
*/
|
*/
|
||||||
static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context)
|
int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context)
|
||||||
{
|
{
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
|
|
||||||
@ -543,14 +543,14 @@ int dhcp_device_init(dhcp_device_context_t **context, const char *intf, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @code dhcp_device_start_capture(context, snaplen, base, vlan_ip);
|
* @code dhcp_device_start_capture(context, snaplen, base, giaddr_ip);
|
||||||
*
|
*
|
||||||
* @brief starts packet capture on this interface
|
* @brief starts packet capture on this interface
|
||||||
*/
|
*/
|
||||||
int dhcp_device_start_capture(dhcp_device_context_t *context,
|
int dhcp_device_start_capture(dhcp_device_context_t *context,
|
||||||
size_t snaplen,
|
size_t snaplen,
|
||||||
struct event_base *base,
|
struct event_base *base,
|
||||||
in_addr_t vlan_ip)
|
in_addr_t giaddr_ip)
|
||||||
{
|
{
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
|
|
||||||
@ -565,7 +565,7 @@ int dhcp_device_start_capture(dhcp_device_context_t *context,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->vlan_ip = vlan_ip;
|
context->giaddr_ip = giaddr_ip;
|
||||||
|
|
||||||
context->buffer = (uint8_t *) malloc(snaplen);
|
context->buffer = (uint8_t *) malloc(snaplen);
|
||||||
if (context->buffer == NULL) {
|
if (context->buffer == NULL) {
|
||||||
|
@ -73,7 +73,7 @@ typedef struct
|
|||||||
int sock; /** Raw socket associated with this device/interface */
|
int sock; /** Raw socket associated with this device/interface */
|
||||||
in_addr_t ip; /** network address of this device (interface) */
|
in_addr_t ip; /** network address of this device (interface) */
|
||||||
uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */
|
uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */
|
||||||
in_addr_t vlan_ip; /** Vlan IP address */
|
in_addr_t giaddr_ip; /** Gateway IP address */
|
||||||
uint8_t is_uplink; /** north interface? */
|
uint8_t is_uplink; /** north interface? */
|
||||||
char intf[IF_NAMESIZE]; /** device (interface) name */
|
char intf[IF_NAMESIZE]; /** device (interface) name */
|
||||||
uint8_t *buffer; /** buffer used to read socket data */
|
uint8_t *buffer; /** buffer used to read socket data */
|
||||||
@ -82,6 +82,17 @@ typedef struct
|
|||||||
/** current/snapshot counters of DHCP packets */
|
/** current/snapshot counters of DHCP packets */
|
||||||
} dhcp_device_context_t;
|
} dhcp_device_context_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @code initialize_intf_mac_and_ip_addr(context);
|
||||||
|
*
|
||||||
|
* @brief initializes device (interface) mac/ip addresses
|
||||||
|
*
|
||||||
|
* @param context pointer to device (interface) context
|
||||||
|
*
|
||||||
|
* @return 0 on success, otherwise for failure
|
||||||
|
*/
|
||||||
|
int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @code dhcp_device_get_ip(context, ip);
|
* @code dhcp_device_get_ip(context, ip);
|
||||||
*
|
*
|
||||||
@ -119,21 +130,21 @@ int dhcp_device_init(dhcp_device_context_t **context,
|
|||||||
uint8_t is_uplink);
|
uint8_t is_uplink);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @code dhcp_device_start_capture(context, snaplen, base, vlan_ip);
|
* @code dhcp_device_start_capture(context, snaplen, base, giaddr_ip);
|
||||||
*
|
*
|
||||||
* @brief starts packet capture on this interface
|
* @brief starts packet capture on this interface
|
||||||
*
|
*
|
||||||
* @param context pointer to device (interface) context
|
* @param context pointer to device (interface) context
|
||||||
* @param snaplen length of packet capture
|
* @param snaplen length of packet capture
|
||||||
* @param base pointer to libevent base
|
* @param base pointer to libevent base
|
||||||
* @param vlan_ip vlan IP address
|
* @param giaddr_ip gateway IP address
|
||||||
*
|
*
|
||||||
* @return 0 on success, otherwise for failure
|
* @return 0 on success, otherwise for failure
|
||||||
*/
|
*/
|
||||||
int dhcp_device_start_capture(dhcp_device_context_t *context,
|
int dhcp_device_start_capture(dhcp_device_context_t *context,
|
||||||
size_t snaplen,
|
size_t snaplen,
|
||||||
struct event_base *base,
|
struct event_base *base,
|
||||||
in_addr_t vlan_ip);
|
in_addr_t giaddr_ip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @code dhcp_device_shutdown(context);
|
* @code dhcp_device_shutdown(context);
|
||||||
|
@ -37,6 +37,12 @@ static uint32_t dhcp_num_mgmt_intf = 0;
|
|||||||
* This IP is used to filter Offer/Ack packet coming from DHCP server */
|
* This IP is used to filter Offer/Ack packet coming from DHCP server */
|
||||||
static in_addr_t vlan_ip = 0;
|
static in_addr_t vlan_ip = 0;
|
||||||
|
|
||||||
|
/* Device loopback interface ip, which will be used as the giaddr in dual tor setup. */
|
||||||
|
static in_addr_t loopback_ip = 0;
|
||||||
|
|
||||||
|
/* Whether the device is in dual tor mode, 0 as default for single tor mode. */
|
||||||
|
static int dual_tor_mode = 0;
|
||||||
|
|
||||||
/** mgmt interface */
|
/** mgmt interface */
|
||||||
static struct intf *mgmt_intf = NULL;
|
static struct intf *mgmt_intf = NULL;
|
||||||
|
|
||||||
@ -148,6 +154,37 @@ int dhcp_devman_add_intf(const char *name, char intf_type)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @code dhcp_devman_setup_dual_tor_mode(name);
|
||||||
|
*
|
||||||
|
* @brief set up dual tor mode: 1) set dual_tor_mode flag and 2) retrieve loopback_ip.
|
||||||
|
*/
|
||||||
|
int dhcp_devman_setup_dual_tor_mode(const char *name)
|
||||||
|
{
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
|
dhcp_device_context_t loopback_intf_context;
|
||||||
|
|
||||||
|
if (strlen(name) < sizeof(loopback_intf_context.intf)) {
|
||||||
|
strncpy(loopback_intf_context.intf, name, sizeof(loopback_intf_context.intf) - 1);
|
||||||
|
loopback_intf_context.intf[sizeof(loopback_intf_context.intf) - 1] = '\0';
|
||||||
|
} else {
|
||||||
|
syslog(LOG_ALERT, "loopback interface name (%s) is too long", name);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialize_intf_mac_and_ip_addr(&loopback_intf_context) == 0 &&
|
||||||
|
dhcp_device_get_ip(&loopback_intf_context, &loopback_ip) == 0) {
|
||||||
|
dual_tor_mode = 1;
|
||||||
|
} else {
|
||||||
|
syslog(LOG_ALERT, "failed to retrieve ip addr for loopback interface (%s)", name);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @code dhcp_devman_start_capture(snaplen, base);
|
* @code dhcp_devman_start_capture(snaplen, base);
|
||||||
*
|
*
|
||||||
@ -160,7 +197,7 @@ int dhcp_devman_start_capture(size_t snaplen, struct event_base *base)
|
|||||||
|
|
||||||
if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) {
|
if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) {
|
||||||
LIST_FOREACH(int_ptr, &intfs, entry) {
|
LIST_FOREACH(int_ptr, &intfs, entry) {
|
||||||
rv = dhcp_device_start_capture(int_ptr->dev_context, snaplen, base, vlan_ip);
|
rv = dhcp_device_start_capture(int_ptr->dev_context, snaplen, base, dual_tor_mode ? loopback_ip : vlan_ip);
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
syslog(LOG_INFO,
|
syslog(LOG_INFO,
|
||||||
"Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n",
|
"Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n",
|
||||||
|
@ -63,6 +63,17 @@ dhcp_device_context_t* dhcp_devman_get_mgmt_dev();
|
|||||||
*/
|
*/
|
||||||
int dhcp_devman_add_intf(const char *name, char intf_type);
|
int dhcp_devman_add_intf(const char *name, char intf_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @code dhcp_devman_setup_dual_tor_mode(name);
|
||||||
|
*
|
||||||
|
* @brief set up dual tor mode: 1) set dual_tor_mode flag and 2) retrieve loopback_ip.
|
||||||
|
*
|
||||||
|
* @param name interface name
|
||||||
|
*
|
||||||
|
* @return 0 on success, nonzero otherwise
|
||||||
|
*/
|
||||||
|
int dhcp_devman_setup_dual_tor_mode(const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @code dhcp_devman_start_capture(snaplen, base);
|
* @code dhcp_devman_start_capture(snaplen, base);
|
||||||
*
|
*
|
||||||
|
@ -40,11 +40,12 @@ static const uint32_t dhcpmon_default_unhealthy_max_count = 10;
|
|||||||
*/
|
*/
|
||||||
static void usage(const char *prog)
|
static void usage(const char *prog)
|
||||||
{
|
{
|
||||||
printf("Usage: %s -id <south interface> {-iu <north interface>}+ -im <mgmt interface> [-w <snapshot window in sec>]"
|
printf("Usage: %s -id <south interface> {-iu <north interface>}+ -im <mgmt interface> [-u <loopback interface>]"
|
||||||
"[-c <unhealthy status count>] [-s <snap length>] [-d]\n", prog);
|
"[-w <snapshot window in sec>] [-c <unhealthy status count>] [-s <snap length>] [-d]\n", prog);
|
||||||
printf("where\n");
|
printf("where\n");
|
||||||
printf("\tsouth interface: is a vlan interface,\n");
|
printf("\tsouth interface: is a vlan interface,\n");
|
||||||
printf("\tnorth interface: is a TOR-T1 interface,\n");
|
printf("\tnorth interface: is a TOR-T1 interface,\n");
|
||||||
|
printf("\tloopback interface: is the loopback interface for dual tor setup,\n");
|
||||||
printf("\tsnapshot window: during which DHCP counters are gathered and DHCP status is validated (default %d),\n",
|
printf("\tsnapshot window: during which DHCP counters are gathered and DHCP status is validated (default %d),\n",
|
||||||
dhcpmon_default_health_check_window);
|
dhcpmon_default_health_check_window);
|
||||||
printf("\tunhealthy status count: count of consecutive unhealthy status before writing an alert to syslog "
|
printf("\tunhealthy status count: count of consecutive unhealthy status before writing an alert to syslog "
|
||||||
@ -132,6 +133,12 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
if (dhcp_devman_setup_dual_tor_mode(argv[i + 1]) != 0) {
|
||||||
|
usage(basename(argv[0]));
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
make_daemon = 1;
|
make_daemon = 1;
|
||||||
i++;
|
i++;
|
||||||
|
Loading…
Reference in New Issue
Block a user