sctp: make IPSec rules effective with IPv6
Subsystems (2)
PATCH 1/1 sctp: make IPSec rules effective with IPv6
IPSec rules are ineffective with IPv6 transmit currently, so this patch make them effective with IPv6.
Idea from Nicolas Dichtel <[email protected]>
--- include/net/sctp/structs.h | 3 +++ net/sctp/ipv6.c | 23 +++++++++++++++++++++++ net/sctp/transport.c | 3 +++ 3 files changed, 29 insertions(+), 0 deletions(-)
include/net/sctp/structs.h +3 -0
@@ -569,6 +569,9 @@ struct sctp_af {struct dst_entry *(*get_dst) (struct sctp_association *asoc,union sctp_addr *daddr,union sctp_addr *saddr); +struct dst_entry *(*get_xfrm_dst)(struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr); void (*get_saddr) (struct sctp_sock *sk, struct sctp_association *asoc, struct dst_entry *dst,
net/sctp/ipv6.c +23 -0
@@ -271,6 +271,28 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,return NULL ; } +static struct dst_entry *sctp_v6_get_xfrm_dst (struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr) +{ +struct flowi fl; + +SCTP_DEBUG_PRINTK ("%s: daddr:%pI6 saddr:%pI6" , + __func__, &daddr->v6.sin6_addr, &saddr->v6.sin6_addr); + +memset (&fl,0 ,sizeof (fl)); + fl.proto =IPPROTO_SCTP ; + fl.fl_ip_dport = daddr->v6.sin6_port; + fl.fl_ip_sport = saddr->v6.sin6_port; +ipv6_addr_copy (&fl.fl6_dst, &daddr->v6.sin6_addr); +ipv6_addr_copy (&fl.fl6_src, &saddr->v6.sin6_addr); + +if (xfrm_lookup (&init_net, dst_p, &fl,NULL ,0 ) <0 ) +return NULL ; +else +return *dst_p; +} +/* Returns the number of consecutive initial bits that match in the 2 ipv6 * addresses. */
@@ -962,6 +984,7 @@ static struct sctp_af sctp_af_inet6 = { .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .get_dst = sctp_v6_get_dst, + .get_xfrm_dst = sctp_v6_get_xfrm_dst, .get_saddr = sctp_v6_get_saddr, .copy_addrlist = sctp_v6_copy_addrlist, .from_skb = sctp_v6_from_skb,
net/sctp/transport.c +3 -0
@@ -298,6 +298,9 @@ void sctp_transport_route(struct sctp_transport *transport,else af->get_saddr (opt, asoc, dst, daddr, &transport->saddr); +if (af->get_xfrm_dst) + dst = af->get_xfrm_dst (&dst, daddr, &transport->saddr); + transport->dst = dst;if ((transport->param_flags &SPP_PMTUD_DISABLE ) && transport->pathmtu) {return ;
Signature · 1 line
1.6.5.2
What about the PMTU problem?
I've understand that this solution will not work:
You wrote:
"This would work for transmit SCTP packet under IPSEC, the problem is that we can not get the correct PMTU for the transport.Under IPv4, both transmit and the PMTU is correct."
Regards,
Nicolas
Quoted 80 lines · Wei Yongjun
IPSec rules are ineffective with IPv6 transmit currently, so this patch make them effective with IPv6.
Idea from Nicolas Dichtel <[email protected]>Signed-off-by Wei Yongjun <[email protected]>--- include/net/sctp/structs.h | 3 +++ net/sctp/ipv6.c | 23 +++++++++++++++++++++++ net/sctp/transport.c | 3 +++ 3 files changed, 29 insertions(+), 0 deletions(-)include/net/sctp/structs.h +3
-0@@ -569,6 +569,9 @@ struct sctp_af {struct dst_entry *(*get_dst) (struct sctp_association *asoc,union sctp_addr *daddr,union sctp_addr *saddr); +struct dst_entry *(*get_xfrm_dst)(struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr); void (*get_saddr) (struct sctp_sock *sk, struct sctp_association *asoc, struct dst_entry *dst,net/sctp/ipv6.c +23
-0@@ -271,6 +271,28 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,return NULL ; } +static struct dst_entry *sctp_v6_get_xfrm_dst (struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr) +{ +struct flowi fl; + +SCTP_DEBUG_PRINTK ("%s: daddr:%pI6 saddr:%pI6" , + __func__, &daddr->v6.sin6_addr, &saddr->v6.sin6_addr); + +memset (&fl,0 ,sizeof (fl)); + fl.proto =IPPROTO_SCTP ; + fl.fl_ip_dport = daddr->v6.sin6_port; + fl.fl_ip_sport = saddr->v6.sin6_port; +ipv6_addr_copy (&fl.fl6_dst, &daddr->v6.sin6_addr); +ipv6_addr_copy (&fl.fl6_src, &saddr->v6.sin6_addr); + +if (xfrm_lookup (&init_net, dst_p, &fl,NULL ,0 ) <0 ) +return NULL ; +else +return *dst_p; +} +/* Returns the number of consecutive initial bits that match in the 2 ipv6 * addresses. */ @@ -962,6 +984,7 @@ static struct sctp_af sctp_af_inet6 = { .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .get_dst = sctp_v6_get_dst, + .get_xfrm_dst = sctp_v6_get_xfrm_dst, .get_saddr = sctp_v6_get_saddr, .copy_addrlist = sctp_v6_copy_addrlist, .from_skb = sctp_v6_from_skb,net/sctp/transport.c +3
-0@@ -298,6 +298,9 @@ void sctp_transport_route(struct sctp_transport *transport,else af->get_saddr (opt, asoc, dst, daddr, &transport->saddr); +if (af->get_xfrm_dst) + dst = af->get_xfrm_dst (&dst, daddr, &transport->saddr); + transport->dst = dst;if ((transport->param_flags &SPP_PMTUD_DISABLE ) && transport->pathmtu) {return ;
Quoted 10 lines
What about the PMTU problem?
I've understand that this solution will not work:
You wrote:
"This would work for transmit SCTP packet under IPSEC, the problem is that we can not get the correct PMTU for the transport.Under IPv4, both transmit and the PMTU is correct."
Yeah, sorry for that, the PMTU problem maybe because I did the wrong thing in the past when I do the same thing. And now when I try to solution it, but works :-( . I do not know whether this implementation has other problem.
Maybe we should do strict route select in sctp_v6_get_dst(), use the address from the asoc or the dev address, do the same thing as IPv4.
Quoted 88 lines
Regards,
NicolasQuoted 81 lines · Wei Yongjun
IPSec rules are ineffective with IPv6 transmit currently, so this patch make them effective with IPv6.
Idea from Nicolas Dichtel <[email protected]>Signed-off-by Wei Yongjun <[email protected]>--- include/net/sctp/structs.h | 3 +++ net/sctp/ipv6.c | 23 +++++++++++++++++++++++ net/sctp/transport.c | 3 +++ 3 files changed, 29 insertions(+), 0 deletions(-)include/net/sctp/structs.h +3
-0@@ -569,6 +569,9 @@ struct sctp_af {struct dst_entry *(*get_dst) (struct sctp_association *asoc,union sctp_addr *daddr,union sctp_addr *saddr); +struct dst_entry *(*get_xfrm_dst)(struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr); void (*get_saddr) (struct sctp_sock *sk, struct sctp_association *asoc, struct dst_entry *dst,net/sctp/ipv6.c +23
-0@@ -271,6 +271,28 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,return NULL ; } +static struct dst_entry *sctp_v6_get_xfrm_dst (struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr) +{ +struct flowi fl; + +SCTP_DEBUG_PRINTK ("%s: daddr:%pI6 saddr:%pI6" , + __func__, &daddr->v6.sin6_addr, &saddr->v6.sin6_addr); + +memset (&fl,0 ,sizeof (fl)); + fl.proto =IPPROTO_SCTP ; + fl.fl_ip_dport = daddr->v6.sin6_port; + fl.fl_ip_sport = saddr->v6.sin6_port; +ipv6_addr_copy (&fl.fl6_dst, &daddr->v6.sin6_addr); +ipv6_addr_copy (&fl.fl6_src, &saddr->v6.sin6_addr); + +if (xfrm_lookup (&init_net, dst_p, &fl,NULL ,0 ) <0 ) +return NULL ; +else +return *dst_p; +} +/* Returns the number of consecutive initial bits that match in the 2 ipv6 * addresses. */ @@ -962,6 +984,7 @@ static struct sctp_af sctp_af_inet6 = { .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .get_dst = sctp_v6_get_dst, + .get_xfrm_dst = sctp_v6_get_xfrm_dst, .get_saddr = sctp_v6_get_saddr, .copy_addrlist = sctp_v6_copy_addrlist, .from_skb = sctp_v6_from_skb,net/sctp/transport.c +3
-0@@ -298,6 +298,9 @@ void sctp_transport_route(struct sctp_transport *transport,else af->get_saddr (opt, asoc, dst, daddr, &transport->saddr); +if (af->get_xfrm_dst) + dst = af->get_xfrm_dst (&dst, daddr, &transport->saddr); + transport->dst = dst;if ((transport->param_flags &SPP_PMTUD_DISABLE ) && transport->pathmtu) {return ;
Quoted 10 lines · Wei Yongjun
Quoted 9 lines
What about the PMTU problem?
I've understand that this solution will not work:
You wrote:
"This would work for transmit SCTP packet under IPSEC, the problem is that we can not get the correct PMTU for the transport.Under IPv4, both transmit and the PMTU is correct."
Quoted 7 lines
Yeah, sorry for that, the PMTU problem maybe because I did the wrong thing in the past when I do the same thing. And now when I try to solution it, but works :-( . I do not know whether this implementation has other problem.
Maybe we should do strict route select in
sctp_v6_get_dst(), use the address from the asoc or the dev address, do the same thing as IPv4.
Yes. This is what should be done. Folks from windriver at looking at fixing that because IPv6 sourced based policy routing is currently broken.
-vlad
Quoted 90 lines
Quoted 89 lines
Regards,
NicolasQuoted 81 lines · Wei Yongjun
IPSec rules are ineffective with IPv6 transmit currently, so this patch make them effective with IPv6.
Idea from Nicolas Dichtel <[email protected]>Signed-off-by Wei Yongjun <[email protected]>--- include/net/sctp/structs.h | 3 +++ net/sctp/ipv6.c | 23 +++++++++++++++++++++++ net/sctp/transport.c | 3 +++ 3 files changed, 29 insertions(+), 0 deletions(-)include/net/sctp/structs.h +3
-0@@ -569,6 +569,9 @@ struct sctp_af {struct dst_entry *(*get_dst) (struct sctp_association *asoc,union sctp_addr *daddr,union sctp_addr *saddr); +struct dst_entry *(*get_xfrm_dst)(struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr); void (*get_saddr) (struct sctp_sock *sk, struct sctp_association *asoc, struct dst_entry *dst,net/sctp/ipv6.c +23
-0@@ -271,6 +271,28 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,return NULL ; } +static struct dst_entry *sctp_v6_get_xfrm_dst (struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr) +{ +struct flowi fl; + +SCTP_DEBUG_PRINTK ("%s: daddr:%pI6 saddr:%pI6" , + __func__, &daddr->v6.sin6_addr, &saddr->v6.sin6_addr); + +memset (&fl,0 ,sizeof (fl)); + fl.proto =IPPROTO_SCTP ; + fl.fl_ip_dport = daddr->v6.sin6_port; + fl.fl_ip_sport = saddr->v6.sin6_port; +ipv6_addr_copy (&fl.fl6_dst, &daddr->v6.sin6_addr); +ipv6_addr_copy (&fl.fl6_src, &saddr->v6.sin6_addr); + +if (xfrm_lookup (&init_net, dst_p, &fl,NULL ,0 ) <0 ) +return NULL ; +else +return *dst_p; +} +/* Returns the number of consecutive initial bits that match in the 2 ipv6 * addresses. */ @@ -962,6 +984,7 @@ static struct sctp_af sctp_af_inet6 = { .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .get_dst = sctp_v6_get_dst, + .get_xfrm_dst = sctp_v6_get_xfrm_dst, .get_saddr = sctp_v6_get_saddr, .copy_addrlist = sctp_v6_copy_addrlist, .from_skb = sctp_v6_from_skb,net/sctp/transport.c +3
-0@@ -298,6 +298,9 @@ void sctp_transport_route(struct sctp_transport *transport,else af->get_saddr (opt, asoc, dst, daddr, &transport->saddr); +if (af->get_xfrm_dst) + dst = af->get_xfrm_dst (&dst, daddr, &transport->saddr); + transport->dst = dst;if ((transport->param_flags &SPP_PMTUD_DISABLE ) && transport->pathmtu) {return ;
Another thread began about the source address problem:
http://marc.info/?t7119843800002&r=1&w=2
Maybe we can fix both problems together. It seems that IPv6 lacks some routing operations.
Regards,
Nicolas
Quoted 106 lines · Wei Yongjun
Quoted 9 lines
What about the PMTU problem?
I've understand that this solution will not work:
You wrote:
"This would work for transmit SCTP packet under IPSEC, the problem is that we can not get the correct PMTU for the transport.Under IPv4, both transmit and the PMTU is correct."Yeah, sorry for that, the PMTU problem maybe because I did the wrong thing in the past when I do the same thing. And now when I try to solution it, but works :-( . I do not know whether this implementation has other problem.
Maybe we should do strict route select in
sctp_v6_get_dst(), use the address from the asoc or the dev address, do the same thing as IPv4.Quoted 87 lines
Regards,
NicolasQuoted 81 lines · Wei Yongjun
IPSec rules are ineffective with IPv6 transmit currently, so this patch make them effective with IPv6.
Idea from Nicolas Dichtel <[email protected]>Signed-off-by Wei Yongjun <[email protected]>--- include/net/sctp/structs.h | 3 +++ net/sctp/ipv6.c | 23 +++++++++++++++++++++++ net/sctp/transport.c | 3 +++ 3 files changed, 29 insertions(+), 0 deletions(-)include/net/sctp/structs.h +3
-0@@ -569,6 +569,9 @@ struct sctp_af {struct dst_entry *(*get_dst) (struct sctp_association *asoc,union sctp_addr *daddr,union sctp_addr *saddr); +struct dst_entry *(*get_xfrm_dst)(struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr); void (*get_saddr) (struct sctp_sock *sk, struct sctp_association *asoc, struct dst_entry *dst,net/sctp/ipv6.c +23
-0@@ -271,6 +271,28 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,return NULL ; } +static struct dst_entry *sctp_v6_get_xfrm_dst (struct dst_entry **dst_p, +union sctp_addr *daddr, +union sctp_addr *saddr) +{ +struct flowi fl; + +SCTP_DEBUG_PRINTK ("%s: daddr:%pI6 saddr:%pI6" , + __func__, &daddr->v6.sin6_addr, &saddr->v6.sin6_addr); + +memset (&fl,0 ,sizeof (fl)); + fl.proto =IPPROTO_SCTP ; + fl.fl_ip_dport = daddr->v6.sin6_port; + fl.fl_ip_sport = saddr->v6.sin6_port; +ipv6_addr_copy (&fl.fl6_dst, &daddr->v6.sin6_addr); +ipv6_addr_copy (&fl.fl6_src, &saddr->v6.sin6_addr); + +if (xfrm_lookup (&init_net, dst_p, &fl,NULL ,0 ) <0 ) +return NULL ; +else +return *dst_p; +} +/* Returns the number of consecutive initial bits that match in the 2 ipv6 * addresses. */ @@ -962,6 +984,7 @@ static struct sctp_af sctp_af_inet6 = { .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .get_dst = sctp_v6_get_dst, + .get_xfrm_dst = sctp_v6_get_xfrm_dst, .get_saddr = sctp_v6_get_saddr, .copy_addrlist = sctp_v6_copy_addrlist, .from_skb = sctp_v6_from_skb,net/sctp/transport.c +3
-0@@ -298,6 +298,9 @@ void sctp_transport_route(struct sctp_transport *transport,else af->get_saddr (opt, asoc, dst, daddr, &transport->saddr); +if (af->get_xfrm_dst) + dst = af->get_xfrm_dst (&dst, daddr, &transport->saddr); + transport->dst = dst;if ((transport->param_flags &SPP_PMTUD_DISABLE ) && transport->pathmtu) {return ;