mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
ipv6: sr: remove cleanup flag and fix HMAC computation
In the latest version of the IPv6 Segment Routing IETF draft [1] the cleanup flag is removed and the flags field length is shrunk from 16 bits to 8 bits. As a consequence, the input of the HMAC computation is modified in a non-backward compatible way by covering the whole octet of flags instead of only the cleanup bit. As such, if an implementation compatible with the latest draft computes the HMAC of an SRH who has other flags set to 1, then the HMAC result would differ from the current implementation. This patch carries those modifications to prevent conflict with other implementations of IPv6 SR. [1] https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-05 Signed-off-by: David Lebrun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
cafe8df8b9
commit
013e816789
3 changed files with 10 additions and 38 deletions
|
|
@ -327,7 +327,6 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
|
|||
struct ipv6_sr_hdr *hdr;
|
||||
struct inet6_dev *idev;
|
||||
struct in6_addr *addr;
|
||||
bool cleanup = false;
|
||||
int accept_seg6;
|
||||
|
||||
hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
|
||||
|
|
@ -351,11 +350,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
|
|||
#endif
|
||||
|
||||
looped_back:
|
||||
if (hdr->segments_left > 0) {
|
||||
if (hdr->nexthdr != NEXTHDR_IPV6 && hdr->segments_left == 1 &&
|
||||
sr_has_cleanup(hdr))
|
||||
cleanup = true;
|
||||
} else {
|
||||
if (hdr->segments_left == 0) {
|
||||
if (hdr->nexthdr == NEXTHDR_IPV6) {
|
||||
int offset = (hdr->hdrlen + 1) << 3;
|
||||
|
||||
|
|
@ -418,21 +413,6 @@ looped_back:
|
|||
|
||||
ipv6_hdr(skb)->daddr = *addr;
|
||||
|
||||
if (cleanup) {
|
||||
int srhlen = (hdr->hdrlen + 1) << 3;
|
||||
int nh = hdr->nexthdr;
|
||||
|
||||
skb_pull_rcsum(skb, sizeof(struct ipv6hdr) + srhlen);
|
||||
memmove(skb_network_header(skb) + srhlen,
|
||||
skb_network_header(skb),
|
||||
(unsigned char *)hdr - skb_network_header(skb));
|
||||
skb->network_header += srhlen;
|
||||
ipv6_hdr(skb)->nexthdr = nh;
|
||||
ipv6_hdr(skb)->payload_len = htons(skb->len -
|
||||
sizeof(struct ipv6hdr));
|
||||
skb_push_rcsum(skb, sizeof(struct ipv6hdr));
|
||||
}
|
||||
|
||||
skb_dst_drop(skb);
|
||||
|
||||
ip6_route_input(skb);
|
||||
|
|
@ -453,13 +433,8 @@ looped_back:
|
|||
}
|
||||
ipv6_hdr(skb)->hop_limit--;
|
||||
|
||||
/* be sure that srh is still present before reinjecting */
|
||||
if (!cleanup) {
|
||||
skb_pull(skb, sizeof(struct ipv6hdr));
|
||||
goto looped_back;
|
||||
}
|
||||
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
|
||||
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
|
||||
skb_pull(skb, sizeof(struct ipv6hdr));
|
||||
goto looped_back;
|
||||
}
|
||||
|
||||
dst_input(skb);
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
|
|||
* hash function (RadioGatun) with up to 1216 bits
|
||||
*/
|
||||
|
||||
/* saddr(16) + first_seg(1) + cleanup(1) + keyid(4) + seglist(16n) */
|
||||
/* saddr(16) + first_seg(1) + flags(1) + keyid(4) + seglist(16n) */
|
||||
plen = 16 + 1 + 1 + 4 + (hdr->first_segment + 1) * 16;
|
||||
|
||||
/* this limit allows for 14 segments */
|
||||
|
|
@ -186,7 +186,7 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
|
|||
*
|
||||
* 1. Source IPv6 address (128 bits)
|
||||
* 2. first_segment value (8 bits)
|
||||
* 3. cleanup flag (8 bits: highest bit is cleanup value, others are 0)
|
||||
* 3. Flags (8 bits)
|
||||
* 4. HMAC Key ID (32 bits)
|
||||
* 5. All segments in the segments list (n * 128 bits)
|
||||
*/
|
||||
|
|
@ -202,8 +202,8 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
|
|||
/* first_segment value */
|
||||
*off++ = hdr->first_segment;
|
||||
|
||||
/* cleanup flag */
|
||||
*off++ = !!(sr_has_cleanup(hdr)) << 7;
|
||||
/* flags */
|
||||
*off++ = hdr->flags;
|
||||
|
||||
/* HMAC Key ID */
|
||||
memcpy(off, &hmackeyid, 4);
|
||||
|
|
|
|||
Loading…
Reference in a new issue