[dhcp-relay]: Modify dhcp relay to pick primary address (#17012)
This is change taken as part of the HLD: sonic-net/SONiC#1470 and this is a follow up on the PR #16827 where in the docker-dhcp we pick the value of primary gateway of the interface from the VLAN_Interface table which has "secondary" flag set in the config_db Microsoft ADO (number only): 16784946 How did I do it - Changes in the j2 file to add a new "-pg" parameter in the dhcpv4-relay.agents.j2, the ip would be retrieved from the config db's vlan_interface table such that the interface which are picked will have secondary field set. - Changes in isc-dhcp to re-order the addresses of the discovered interface and which has the ip which has the passed parameter.
This commit is contained in:
parent
aea3c42f29
commit
8b192a1151
@ -24,6 +24,9 @@ command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /t
|
|||||||
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
|
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
|
||||||
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
|
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% for (name, gateway) in VLAN_INTERFACE|get_primary_addr %}
|
||||||
|
{% if gateway | ipv4 and name == vlan_name %} -pg {{ gateway }}{% endif -%}
|
||||||
|
{% endfor %}
|
||||||
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
|
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
|
||||||
{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%}
|
{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
diff --git a/common/discover.c b/common/discover.c
|
||||||
|
index ab50234..40e13f5 100644
|
||||||
|
--- a/common/discover.c
|
||||||
|
+++ b/common/discover.c
|
||||||
|
@@ -1614,3 +1614,16 @@ void interface_snorf (struct interface_info *tmp, int ir)
|
||||||
|
}
|
||||||
|
interface_reference (&interfaces, tmp, MDL);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void set_primary_addr_in_intf (struct in_addr primary_addr) {
|
||||||
|
+ for (struct interface_info *tmp = interfaces; tmp; tmp = tmp->next) {
|
||||||
|
+ for (int i = 0; i < tmp->address_count; i++) {
|
||||||
|
+ if (tmp->addresses[i].s_addr == primary_addr.s_addr) {
|
||||||
|
+ struct in_addr tmp_ip = tmp->addresses[0];
|
||||||
|
+ tmp->addresses[0] = primary_addr;
|
||||||
|
+ tmp->addresses[i] = tmp_ip;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||||
|
index 257b31e..e7f9f06 100644
|
||||||
|
--- a/includes/dhcpd.h
|
||||||
|
+++ b/includes/dhcpd.h
|
||||||
|
@@ -2873,6 +2873,7 @@ extern int interface_count;
|
||||||
|
extern int interface_max;
|
||||||
|
isc_result_t interface_initialize(omapi_object_t *, const char *, int);
|
||||||
|
void discover_interfaces(int);
|
||||||
|
+void set_primary_addr_in_intf (struct in_addr );
|
||||||
|
int setup_fallback (struct interface_info **, const char *, int);
|
||||||
|
int if_readsocket (omapi_object_t *);
|
||||||
|
void reinitialize_interfaces (void);
|
||||||
|
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||||
|
index ff0ad17..31fe61b 100644
|
||||||
|
--- a/relay/dhcrelay.c
|
||||||
|
+++ b/relay/dhcrelay.c
|
||||||
|
@@ -92,6 +92,11 @@ struct downstream_intf_list {
|
||||||
|
struct interface_info *interface;
|
||||||
|
} *downstream_intfs = NULL;
|
||||||
|
|
||||||
|
+struct primary_gw_list {
|
||||||
|
+ struct primary_gw_list *next;
|
||||||
|
+ struct in_addr gateway_addr;
|
||||||
|
+} *primary_gws = NULL;
|
||||||
|
+
|
||||||
|
#ifdef DHCPv6
|
||||||
|
/* Force use of DHCPv6 interface-id option. */
|
||||||
|
isc_boolean_t use_if_id = ISC_FALSE;
|
||||||
|
@@ -199,6 +204,7 @@ char *progname;
|
||||||
|
" [-i interface0 [ ... -i interfaceN]\n" \
|
||||||
|
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||||
|
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||||
|
+" [-pg ip-address0 [ ... -pg ip-addressN]]\n" \
|
||||||
|
" [-U interface]\n" \
|
||||||
|
" [-dt]\n"\
|
||||||
|
" server0 [ ... serverN]\n\n" \
|
||||||
|
@@ -221,6 +227,7 @@ char *progname;
|
||||||
|
" [-i interface0 [ ... -i interfaceN]\n" \
|
||||||
|
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||||
|
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||||
|
+" [-pg ip-address0 [ ... -pg ip-addressN]]\n" \
|
||||||
|
" [-U interface]\n" \
|
||||||
|
" [-dt]\n"\
|
||||||
|
" server0 [ ... serverN]\n\n" \
|
||||||
|
@@ -649,6 +656,34 @@ main(int argc, char **argv) {
|
||||||
|
usage(use_noarg, argv[i-1]);
|
||||||
|
path_dhcrelay_pid = argv[i];
|
||||||
|
no_dhcrelay_pid = ISC_TRUE;
|
||||||
|
+ } else if (!strcmp(argv[i], "-pg")) {
|
||||||
|
+ if (++i == argc)
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+#ifdef DHCPv6
|
||||||
|
+ if (local_family_set && (local_family == AF_INET6)) {
|
||||||
|
+ usage(use_v4command, argv[i]);
|
||||||
|
+ }
|
||||||
|
+ local_family_set = 1;
|
||||||
|
+ local_family = AF_INET;
|
||||||
|
+#endif
|
||||||
|
+ struct in_addr gw = {0};
|
||||||
|
+ if (inet_pton(AF_INET, argv[i], &gw) <= 0) {
|
||||||
|
+ usage("Invalid gateway address '%s'", argv[i]);
|
||||||
|
+ } else {
|
||||||
|
+ struct primary_gw_list *pg = ((struct primary_gw_list *)dmalloc(sizeof(struct primary_gw_list), MDL));
|
||||||
|
+ pg->gateway_addr = gw;
|
||||||
|
+ pg->next = NULL;
|
||||||
|
+
|
||||||
|
+ if (primary_gws == NULL) {
|
||||||
|
+ primary_gws = pg;
|
||||||
|
+ } else {
|
||||||
|
+ struct primary_gw_list *tmp = primary_gws;
|
||||||
|
+ while (tmp->next != NULL) {
|
||||||
|
+ tmp = tmp->next;
|
||||||
|
+ }
|
||||||
|
+ tmp->next = pg;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
} else if (!strcmp(argv[i], "--no-pid")) {
|
||||||
|
no_pid_file = ISC_TRUE;
|
||||||
|
} else if (!strcmp(argv[i], "--name-alias-map-file")) {
|
||||||
|
@@ -818,6 +853,12 @@ main(int argc, char **argv) {
|
||||||
|
/* Discover all the network interfaces. */
|
||||||
|
discover_interfaces(DISCOVER_RELAY);
|
||||||
|
|
||||||
|
+ struct primary_gw_list *tmp = primary_gws;
|
||||||
|
+ while (tmp != NULL) {
|
||||||
|
+ set_primary_addr_in_intf(tmp->gateway_addr);
|
||||||
|
+ tmp = tmp->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
#ifdef DHCPv6
|
||||||
|
if (local_family == AF_INET6)
|
||||||
|
setup_streams();
|
@ -13,3 +13,4 @@
|
|||||||
0012-add-option-si-to-support-using-src-intf-ip-in-relay.patch
|
0012-add-option-si-to-support-using-src-intf-ip-in-relay.patch
|
||||||
0013-Fix-dhcrelay-agent-option-buffer-pointer-logic.patch
|
0013-Fix-dhcrelay-agent-option-buffer-pointer-logic.patch
|
||||||
0014-enable-parallel-build.patch
|
0014-enable-parallel-build.patch
|
||||||
|
0015-option-to-set-primary-address-in-interface.patch
|
||||||
|
@ -25,6 +25,7 @@ import netaddr
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import yaml
|
import yaml
|
||||||
|
import ipaddress
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from config_samples import generate_sample_config, get_available_config
|
from config_samples import generate_sample_config, get_available_config
|
||||||
@ -137,6 +138,27 @@ def ip_network(value):
|
|||||||
return "Invalid ip address %s" % value
|
return "Invalid ip address %s" % value
|
||||||
return r_v.network
|
return r_v.network
|
||||||
|
|
||||||
|
def get_primary_addr(value):
|
||||||
|
if not value:
|
||||||
|
return ""
|
||||||
|
table = pfx_filter(value)
|
||||||
|
primary_gateways = OrderedDict()
|
||||||
|
intf_with_secondary = set()
|
||||||
|
for key, val in table.items():
|
||||||
|
name, prefix = key
|
||||||
|
if "secondary" in val:
|
||||||
|
intf_with_secondary.add(name)
|
||||||
|
for key, val in table.items():
|
||||||
|
name, prefix = key
|
||||||
|
if name in intf_with_secondary and "secondary" not in val:
|
||||||
|
if PY3x:
|
||||||
|
network_def = ipaddress.ip_network(prefix, strict=False)
|
||||||
|
else:
|
||||||
|
network_def = ipaddress.ip_network(unicode(prefix), strict=False)
|
||||||
|
primary_gateways[(name, network_def[1])] = {}
|
||||||
|
intf_with_secondary.remove(name)
|
||||||
|
return primary_gateways
|
||||||
|
|
||||||
def load_namespace_config(asic_name):
|
def load_namespace_config(asic_name):
|
||||||
if not SonicDBConfig.isInit():
|
if not SonicDBConfig.isInit():
|
||||||
if is_multi_asic():
|
if is_multi_asic():
|
||||||
@ -247,6 +269,7 @@ def _get_jinja2_env(paths):
|
|||||||
env.filters['unique_name'] = unique_name
|
env.filters['unique_name'] = unique_name
|
||||||
env.filters['pfx_filter'] = pfx_filter
|
env.filters['pfx_filter'] = pfx_filter
|
||||||
env.filters['ip_network'] = ip_network
|
env.filters['ip_network'] = ip_network
|
||||||
|
env.filters['get_primary_addr'] = get_primary_addr
|
||||||
for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']:
|
for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']:
|
||||||
env.filters[attr] = partial(prefix_attr, attr)
|
env.filters[attr] = partial(prefix_attr, attr)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user