zebra: include MTU option in RA on request (BZ#665)

This implements a new "ipv6 nd mtu <1-65535>" interface-level command.

* doc/ipv6.texi: add description
* zebra/rtadv.c
  * rtadv_send_packet(): send option type 5, when configured
  * ipv6_nd_mtu(): new VTY helper
  * no_ipv6_nd_mtu(): ditto
  * rtadv_config_write(): add new option
  * rtadv_init(): list new helpers
This commit is contained in:
Denis Ovsienko 2011-12-27 10:45:36 +04:00
parent fc98d16ea7
commit 6ae93c0587
2 changed files with 63 additions and 0 deletions

View File

@ -157,6 +157,15 @@ Set default router preference in IPv6 router advertisements per RFC4191.
Default: medium
@end deffn
@deffn {Interface Command} {ipv6 nd mtu <1-65535>} {}
@deffnx {Interface Command} {no ipv6 nd mtu [<1-65535>]} {}
Include an MTU (type 5) option in each RA packet to assist the attached hosts
in proper interface configuration. The announced value is not verified to be
consistent with router interface MTU.
Default: don't advertise any MTU option
@end deffn
@example
@group
interface eth0

View File

@ -319,6 +319,17 @@ rtadv_send_packet (int sock, struct interface *ifp)
}
#endif /* HAVE_STRUCT_SOCKADDR_DL */
/* MTU */
if (zif->rtadv.AdvLinkMTU)
{
struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
opt->nd_opt_mtu_type = ND_OPT_MTU;
opt->nd_opt_mtu_len = 1;
opt->nd_opt_mtu_reserved = 0;
opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
len += sizeof (struct nd_opt_mtu);
}
msg.msg_name = (void *) &addr;
msg.msg_namelen = sizeof (struct sockaddr_in6);
msg.msg_iov = &iov;
@ -1430,6 +1441,43 @@ DEFUN (no_ipv6_nd_router_preference,
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_mtu,
ipv6_nd_mtu_cmd,
"ipv6 nd mtu <1-65535>",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Advertised MTU\n"
"MTU in bytes\n")
{
struct interface *ifp = (struct interface *) vty->index;
struct zebra_if *zif = ifp->info;
VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_mtu,
no_ipv6_nd_mtu_cmd,
"no ipv6 nd mtu",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Advertised MTU\n")
{
struct interface *ifp = (struct interface *) vty->index;
struct zebra_if *zif = ifp->info;
zif->rtadv.AdvLinkMTU = 0;
return CMD_SUCCESS;
}
ALIAS (no_ipv6_nd_mtu,
no_ipv6_nd_mtu_val_cmd,
"no ipv6 nd mtu <1-65535>",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Advertised MTU\n"
"MTU in bytes\n")
/* Write configuration about router advertisement. */
void
rtadv_config_write (struct vty *vty, struct interface *ifp)
@ -1482,6 +1530,9 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
rtadv_pref_strs[zif->rtadv.DefaultPreference],
VTY_NEWLINE);
if (zif->rtadv.AdvLinkMTU)
vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
{
vty_out (vty, " ipv6 nd prefix %s/%d",
@ -1605,6 +1656,9 @@ rtadv_init (void)
install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
}
static int