diff options
Diffstat (limited to 'server/dhcp.c')
-rw-r--r-- | server/dhcp.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/server/dhcp.c b/server/dhcp.c index 58072c93..03815948 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -4360,6 +4360,7 @@ int locate_network (packet) struct data_string data; struct subnet *subnet = (struct subnet *)0; struct option_cache *oc; + int sso = 0; /* See if there's a Relay Agent Link Selection Option, or a * Subnet Selection Option. The Link-Select and Subnet-Select @@ -4370,10 +4371,44 @@ int locate_network (packet) RAI_LINK_SELECT)) == NULL) oc = lookup_option(&dhcp_universe, packet->options, DHO_SUBNET_SELECTION); + if (oc) + sso = 1; + +#ifdef DHCPv6 + /* See if there is a Relay Agent CRA6ADDR Option. */ + if (!sso) + oc = lookup_option(&agent_universe, packet->options, + RAI_CRA6ADDR); + if (!sso && oc) { + memset (&data, 0, sizeof data); + if (!evaluate_option_cache (&data, packet, (struct lease *)0, + (struct client_state *)0, + packet -> options, + (struct option_state *)0, + &global_scope, oc, MDL)) { + return 0; + } + if (data.len != 16) { + return 0; + } + ia.len = 16; + memcpy (ia.iabuf, data.data, 16); + data_string_forget (&data, MDL); + + /* Get the subnet of this IPv6 address. */ + if (find_subnet (&subnet, ia, MDL)) { + shared_network_reference (&packet -> shared_network, + subnet -> shared_network, + MDL); + subnet_dereference (&subnet, MDL); + return 1; + } + } +#endif /* If there's no SSO and no giaddr, then use the shared_network from the interface, if there is one. If not, fail. */ - if (!oc && !packet -> raw -> giaddr.s_addr) { + if (!sso && !packet -> raw -> giaddr.s_addr) { if (packet -> interface -> shared_network) { shared_network_reference (&packet -> shared_network, @@ -4386,7 +4421,7 @@ int locate_network (packet) /* If there's an option indicating link connection, and it's valid, * use it to figure out the subnet. If it's not valid, fail. */ - if (oc) { + if (sso) { memset (&data, 0, sizeof data); if (!evaluate_option_cache (&data, packet, (struct lease *)0, (struct client_state *)0, |