summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2011-09-28 14:23:35 +0400
committerDenis Ovsienko <infrastation@yandex.ru>2011-10-17 18:13:28 +0400
commitd1e2faa40e17fe8f3db591021994d2f5e8b11335 (patch)
tree4ca879fbf8ba3b7932c7b180f22d477dd9e3536a
parent792b6fa2c40f820df07caa80fbc6ed9c4191ef9b (diff)
IPv6 transport class suppport
IPv6 supports the same concept of differentiated service for routing protocols as IPv4, but like too many things, the standards committee decided that having two names for the same thing wasn't good enough and introduced a third more generic term transport class. The socket option to set transport class works the same as IPv4, but the arguments are different. * lib/sockopt.[ch] * setsockopt_ipv6_tclass(): new function * bgpd/bgp_network.c * bgp_connect(): set socket option * bgp_listener(): set socket option * ospf6d/ospf6_network.c * ospf6_set_transport_class(): new function * ospf6_serv_sock(): set socket option * ripngd/ripngd.c * ripng_make_socket(): set socket option
-rw-r--r--bgpd/bgp_network.c8
-rw-r--r--lib/sockopt.c13
-rw-r--r--lib/sockopt.h1
-rw-r--r--ospf6d/ospf6_network.c9
-rw-r--r--ripngd/ripngd.c5
5 files changed, 35 insertions, 1 deletions
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 9e3427d2..b5fa948c 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -322,6 +322,10 @@ bgp_connect (struct peer *peer)
#ifdef IPTOS_PREC_INTERNETCONTROL
if (sockunion_family (&peer->su) == AF_INET)
setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
+# ifdef HAVE_IPV6
+ else if (sockunion_family (&peer->su) == AF_INET6)
+ setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
+# endif
#endif
if (peer->password)
@@ -381,6 +385,10 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
#ifdef IPTOS_PREC_INTERNETCONTROL
if (sa->sa_family == AF_INET)
setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);
+# ifdef HAVE_IPV6
+ else if (sa->sa_family == AF_INET6)
+ setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL);
+# endif
#endif
#ifdef IPV6_V6ONLY
diff --git a/lib/sockopt.c b/lib/sockopt.c
index 9ff15ca6..63858408 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -179,8 +179,19 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh)
return pktinfo->ipi6_ifindex;
}
-#endif /* HAVE_IPV6 */
+int
+setsockopt_ipv6_tclass(int sock, int tclass)
+{
+ int ret;
+
+ ret = setsockopt (sock, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof (tclass));
+ if (ret < 0)
+ zlog_warn ("Can't set IPV6_TCLASS option for fd %d to %#x: %s",
+ sock, tclass, safe_strerror(errno));
+ return ret;
+}
+#endif /* HAVE_IPV6 */
/*
* Process multicast socket options for IPv4 in an OS-dependent manner.
diff --git a/lib/sockopt.h b/lib/sockopt.h
index 69309e00..aced6d48 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -35,6 +35,7 @@ extern int setsockopt_ipv6_multicast_hops (int, int);
extern int setsockopt_ipv6_unicast_hops (int, int);
extern int setsockopt_ipv6_hoplimit (int, int);
extern int setsockopt_ipv6_multicast_loop (int, int);
+extern int setsockopt_ipv6_tclass (int, int);
#endif /* HAVE_IPV6 */
/*
diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c
index 96b82af3..3372238b 100644
--- a/ospf6d/ospf6_network.c
+++ b/ospf6d/ospf6_network.c
@@ -64,6 +64,14 @@ ospf6_set_pktinfo (void)
}
void
+ospf6_set_transport_class (void)
+{
+#ifdef IPTOS_PREC_INTERNETCONTROL
+ setsockopt_ipv6_tclass (ospf6_sock, IPTOS_PREC_INTERNETCONTROL);
+#endif
+}
+
+void
ospf6_set_checksum (void)
{
int offset = 12;
@@ -102,6 +110,7 @@ ospf6_serv_sock (void)
#endif /*1*/
ospf6_reset_mcastloop ();
ospf6_set_pktinfo ();
+ ospf6_set_transport_class ();
ospf6_set_checksum ();
/* setup global in6_addr, allspf6 and alldr6 for later use */
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 6e32d83c..d416255c 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -117,6 +117,11 @@ ripng_make_socket (void)
ret = setsockopt_ipv6_pktinfo (sock, 1);
if (ret < 0)
return ret;
+#ifdef IPTOS_PREC_INTERNETCONTROL
+ ret = setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL);
+ if (ret < 0)
+ return ret;
+#endif
ret = setsockopt_ipv6_multicast_hops (sock, 255);
if (ret < 0)
return ret;