Skip to content

Commit

Permalink
Fix dhcpmon
Browse files Browse the repository at this point in the history
  • Loading branch information
shlomibitton authored and yxieca committed Oct 26, 2021
1 parent 5737c22 commit e30d559
Show file tree
Hide file tree
Showing 10 changed files with 361 additions and 93 deletions.
2 changes: 2 additions & 0 deletions dockers/docker-dhcp-relay/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ RUN rm -rf /debs

COPY ["docker_init.sh", "start.sh", "/usr/bin/"]
COPY ["docker-dhcp-relay.supervisord.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"]
COPY ["dhcp-relay.programs.j2", "dhcpv4-relay.agents.j2", "dhcpv6-relay.agents.j2", "dhcpv6-relay.monitors.j2", "/usr/share/sonic/templates/"]
COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]

ENTRYPOINT ["/usr/bin/docker_init.sh"]
17 changes: 17 additions & 0 deletions dockers/docker-dhcp-relay/dhcp-relay.programs.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[group:isc-dhcp-relay]
programs=
{%- set add_preceding_comma = { 'flag': False } %}
{% for vlan_name in VLAN_INTERFACE %}
{# Append DHCPv4 agents #}
{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
{% if add_preceding_comma.flag %},{% endif %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
isc-dhcpv4-relay-{{ vlan_name }}
{%- endif %}
{# Append DHCPv6 agents #}
{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
{% if add_preceding_comma.flag %},{% endif %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
isc-dhcpv6-relay-{{ vlan_name }}
{%- endif %}
{% endfor %}
40 changes: 40 additions & 0 deletions dockers/docker-dhcp-relay/dhcpv4-relay.agents.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{# Append DHCPv4 agents #}
{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
{% if dhcp_server | ipv4 %}
{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
{% endif %}
{% endfor %}
{% if relay_for_ipv4.flag %}
{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
[program:isc-dhcpv4-relay-{{ vlan_name }}]
{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }}
{#- Dual ToR Option #}
{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %} -U Loopback0 -dt{% endif -%}
{#- si option to use intf addr in relay #}
{% if DEVICE_METADATA['localhost']['deployment_id'] == '8' %} -si{% endif -%}
{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in INTERFACE|pfx_filter %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%}
{% endfor %}

priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited

{% endif %}
{% endif %}
37 changes: 37 additions & 0 deletions dockers/docker-dhcp-relay/dhcpv6-relay.agents.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{# Append DHCPv6 agents #}
{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
{% for dhcpv6_server in VLAN[vlan_name]['dhcpv6_servers'] %}
{% if dhcpv6_server | ipv6 %}
{% set _dummy = relay_for_ipv6.update({'flag': True}) %}
{% endif %}
{% endfor %}
{% if relay_for_ipv6.flag %}
{% set _dummy = relay_for_ipv6.update({'flag': False}) %}
[program:isc-dhcpv6-relay-{{ vlan_name }}]
{# We treat this VLAN as a downstream interface (-l), as we only want to listen for requests #}
command=/usr/sbin/dhcrelay -d -6 --name-alias-map-file /tmp/port-name-alias-map.txt -l {{ vlan_name }}
{#- We treat all other interfaces as upstream interfaces (-u), as we only want to listen for replies #}
{%- for dhcpv6_server in VLAN[vlan_name]['dhcpv6_servers'] %}
{%- if dhcpv6_server | ipv6 %}
{%- for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
{%- if prefix | ipv6 and name != vlan_name %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
{% endfor %}
{% for (name, prefix) in INTERFACE|pfx_filter %}
{% if prefix | ipv6 %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
{% endfor %}
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
{% if prefix | ipv6 %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
{% endfor %}
{% endif -%}
{% endfor %}

priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited

{% endif %}
{% endif %}
79 changes: 79 additions & 0 deletions dockers/docker-dhcp-relay/dhcpv6-relay.monitors.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[group:dhcpmon]
programs=
{%- set add_preceding_comma = { 'flag': False } %}
{% set monitor_instance = { 'flag': False } %}
{% for vlan_name in VLAN_INTERFACE %}
{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
{% set _dummy = monitor_instance.update({'flag': True}) %}
{%- endif %}
{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
{% set _dummy = monitor_instance.update({'flag': True}) %}
{%- endif %}
{% if monitor_instance.flag %}
{% if add_preceding_comma.flag %},{% endif %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
dhcpmon-{{ vlan_name }}
{%- set _dummy = monitor_instance.update({'flag': False}) %}
{%- endif %}
{% endfor %}


{# Create a program entry for each DHCP MONitor instance #}
{% set relay_for_ipv4 = { 'flag': False } %}
{% set relay_for_ipv6 = { 'flag': False } %}
{% for vlan_name in VLAN_INTERFACE %}
{# Check DHCPv4 agents #}
{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
{% if dhcp_server | ipv4 %}
{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
{% endif %}
{% endfor %}
{% endif %}
{# Check DHCPv6 agents #}
{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
{% for dhcpv6_server in VLAN[vlan_name]['dhcpv6_servers'] %}
{% if dhcpv6_server | ipv6 %}
{% set _dummy = relay_for_ipv6.update({'flag': True}) %}
{% endif %}
{% endfor %}
{% endif %}
{% if relay_for_ipv4.flag or relay_for_ipv6.flag %}
[program:dhcpmon-{{ vlan_name }}]
{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
command=/usr/sbin/dhcpmon -id {{ vlan_name }}
{#- Dual ToR Option #}
{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %} -u Loopback0{% endif -%}
{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in INTERFACE|pfx_filter %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% if MGMT_INTERFACE %}
{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %}
{% if prefix | ipv4 %} -im {{ name }}{% endif -%}
{% endfor %}
{% endif %}
{% if relay_for_ipv4.flag %} -4{% endif %}
{% if relay_for_ipv6.flag %} -6{% endif %}

priority=4
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=
{%- if relay_for_ipv4.flag %}isc-dhcpv4-relay-{{ vlan_name }}:running {% endif %}
{% if relay_for_ipv6.flag %}isc-dhcpv6-relay-{{ vlan_name }}:running{% endif %}


{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
{% set _dummy = relay_for_ipv6.update({'flag': False}) %}
{% endif %}
{% endfor %}
105 changes: 15 additions & 90 deletions dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -29,104 +29,29 @@ stderr_logfile=syslog
{% endfor %}
{% set vlan_list = d.vlan_list %}
{# Count how many VLANs require a DHCP relay agent... #}
{% set num_relays = { 'count': 0 } %}
{% for vlan_name in vlan_list %}
{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %}
{% set _dummy = num_relays.update({'count': num_relays.count + 1}) %}
{% set ipv4_num_relays = { 'count': 0 } %}
{% set ipv6_num_relays = { 'count': 0 } %}
{% for vlan_name in VLAN_INTERFACE %}
{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
{% set _dummy = ipv4_num_relays.update({'count': ipv4_num_relays.count + 1}) %}
{% endif %}
{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
{% set _dummy = ipv6_num_relays.update({'count': ipv6_num_relays.count + 1}) %}
{% endif %}
{% endfor %}
{# If one or more of the VLANs require a DHCP relay agent... #}
{% if num_relays.count > 0 %}
[group:isc-dhcp-relay]
programs=
{%- set add_preceding_comma = { 'flag': False } %}
{% for vlan_name in vlan_list %}
{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %}
{% if add_preceding_comma.flag %},{% endif %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
isc-dhcp-relay-{{ vlan_name }}
{%- endif %}
{% endfor %}
{% if ipv4_num_relays.count > 0 or ipv6_num_relays.count > 0 %}
{% include 'dhcp-relay.programs.j2' %}


{# Create a program entry for each DHCP relay agent instance #}
{% for vlan_name in vlan_list %}
{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %}
[program:isc-dhcp-relay-{{ vlan_name }}]
{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }}
{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
{% for (name, prefix) in VLAN_INTERFACE %}
{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in INTERFACE %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in PORTCHANNEL_INTERFACE %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} {{ dhcp_server }}{% endfor %}

priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

{% endif %}
{% endfor %}

[group:dhcpmon]
programs=
{%- set add_preceding_comma = { 'flag': False } %}
{% for vlan_name in vlan_list %}
{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %}
{% if add_preceding_comma.flag %},{% endif %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
dhcpmon-{{ vlan_name }}
{%- endif %}
{% endfor %}


{# Create a program entry for each DHCP MONitor instance #}
{% set relay_for_ipv4 = { 'flag': False } %}
{% for vlan_name in vlan_list %}
{% if VLAN and vlan_name in VLAN and VLAN[vlan_name]['dhcp_servers'] %}
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
{% if dhcp_server | ipv4 %}
{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
{% endif %}
{% endfor %}
{% if relay_for_ipv4.flag %}
{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
[program:dhcpmon-{{ vlan_name }}]
{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
command=/usr/sbin/dhcpmon -id {{ vlan_name }}
{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
{% for (name, prefix) in VLAN_INTERFACE %}
{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in INTERFACE %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, prefix) in PORTCHANNEL_INTERFACE %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% if MGMT_INTERFACE %}
{% for (name, prefix) in MGMT_INTERFACE %}
{% if prefix | ipv4 %} -im {{ name }}{% endif -%}
{% endfor %}
{% endif %}

priority=4
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

{% endif %}
{% endif %}
{% set relay_for_ipv6 = { 'flag': False } %}
{% for vlan_name in VLAN_INTERFACE %}
{% include 'dhcpv4-relay.agents.j2' %}
{% include 'dhcpv6-relay.agents.j2' %}
{% endfor %}

{% include 'dhcpv6-relay.monitors.j2' %}
{% endif %}
{% endif %}
5 changes: 2 additions & 3 deletions src/dhcpmon/src/dhcp_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <arpa/inet.h>
#include <unistd.h>
#include <syslog.h>
#include <libexplain/ioctl.h>
#include <linux/filter.h>
#include <netpacket/packet.h>
#include <sys/types.h>
Expand Down Expand Up @@ -686,14 +685,14 @@ int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context)

// Get v4 network address
if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) {
syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFADDR, &ifr));
syslog(LOG_ALERT, "ioctl: %s", strerror(errno));
break;
}
context->ipv4 = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr;

// Get mac address
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFHWADDR, &ifr));
syslog(LOG_ALERT, "ioctl: %s", strerror(errno));
break;
}
memcpy(context->mac, ifr.ifr_hwaddr.sa_data, sizeof(context->mac));
Expand Down
11 changes: 11 additions & 0 deletions src/dhcpmon/src/dhcp_devman.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
*
Expand Down
Loading

0 comments on commit e30d559

Please sign in to comment.