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:
|
||||
giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 |
|
||||
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->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_ACK:
|
||||
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->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
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -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
|
||||
*/
|
||||
int dhcp_device_start_capture(dhcp_device_context_t *context,
|
||||
size_t snaplen,
|
||||
struct event_base *base,
|
||||
in_addr_t vlan_ip)
|
||||
in_addr_t giaddr_ip)
|
||||
{
|
||||
int rv = -1;
|
||||
|
||||
@ -565,7 +565,7 @@ int dhcp_device_start_capture(dhcp_device_context_t *context,
|
||||
break;
|
||||
}
|
||||
|
||||
context->vlan_ip = vlan_ip;
|
||||
context->giaddr_ip = giaddr_ip;
|
||||
|
||||
context->buffer = (uint8_t *) malloc(snaplen);
|
||||
if (context->buffer == NULL) {
|
||||
|
@ -73,7 +73,7 @@ typedef struct
|
||||
int sock; /** Raw socket associated with 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) */
|
||||
in_addr_t vlan_ip; /** Vlan IP address */
|
||||
in_addr_t giaddr_ip; /** Gateway IP address */
|
||||
uint8_t is_uplink; /** north interface? */
|
||||
char intf[IF_NAMESIZE]; /** device (interface) name */
|
||||
uint8_t *buffer; /** buffer used to read socket data */
|
||||
@ -82,6 +82,17 @@ typedef struct
|
||||
/** current/snapshot counters of DHCP packets */
|
||||
} 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);
|
||||
*
|
||||
@ -119,21 +130,21 @@ int dhcp_device_init(dhcp_device_context_t **context,
|
||||
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
|
||||
*
|
||||
* @param context pointer to device (interface) context
|
||||
* @param snaplen length of packet capture
|
||||
* @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
|
||||
*/
|
||||
int dhcp_device_start_capture(dhcp_device_context_t *context,
|
||||
size_t snaplen,
|
||||
struct event_base *base,
|
||||
in_addr_t vlan_ip);
|
||||
in_addr_t giaddr_ip);
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
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 */
|
||||
static struct intf *mgmt_intf = NULL;
|
||||
|
||||
@ -148,6 +154,37 @@ int dhcp_devman_add_intf(const char *name, char intf_type)
|
||||
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);
|
||||
*
|
||||
@ -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)) {
|
||||
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) {
|
||||
syslog(LOG_INFO,
|
||||
"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);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
*
|
||||
|
@ -40,11 +40,12 @@ static const uint32_t dhcpmon_default_unhealthy_max_count = 10;
|
||||
*/
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
printf("Usage: %s -id <south interface> {-iu <north interface>}+ -im <mgmt interface> [-w <snapshot window in sec>]"
|
||||
"[-c <unhealthy status count>] [-s <snap length>] [-d]\n", prog);
|
||||
printf("Usage: %s -id <south interface> {-iu <north interface>}+ -im <mgmt interface> [-u <loopback interface>]"
|
||||
"[-w <snapshot window in sec>] [-c <unhealthy status count>] [-s <snap length>] [-d]\n", prog);
|
||||
printf("where\n");
|
||||
printf("\tsouth interface: is a vlan 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",
|
||||
dhcpmon_default_health_check_window);
|
||||
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;
|
||||
break;
|
||||
case 'u':
|
||||
if (dhcp_devman_setup_dual_tor_mode(argv[i + 1]) != 0) {
|
||||
usage(basename(argv[0]));
|
||||
}
|
||||
i += 2;
|
||||
break;
|
||||
case 'd':
|
||||
make_daemon = 1;
|
||||
i++;
|
||||
|
Loading…
Reference in New Issue
Block a user