ipv6: add ip6_sock_set_addr_preferences
Add a helper to directly set the IPV6_ADD_PREFERENCES sockopt from kernel space without going through a fake uaccess. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
fce934949c
commit
18d5ad6232
@@ -845,67 +845,10 @@ done:
|
||||
break;
|
||||
|
||||
case IPV6_ADDR_PREFERENCES:
|
||||
{
|
||||
unsigned int pref = 0;
|
||||
unsigned int prefmask = ~0;
|
||||
|
||||
if (optlen < sizeof(int))
|
||||
goto e_inval;
|
||||
|
||||
retv = -EINVAL;
|
||||
|
||||
/* check PUBLIC/TMP/PUBTMP_DEFAULT conflicts */
|
||||
switch (val & (IPV6_PREFER_SRC_PUBLIC|
|
||||
IPV6_PREFER_SRC_TMP|
|
||||
IPV6_PREFER_SRC_PUBTMP_DEFAULT)) {
|
||||
case IPV6_PREFER_SRC_PUBLIC:
|
||||
pref |= IPV6_PREFER_SRC_PUBLIC;
|
||||
break;
|
||||
case IPV6_PREFER_SRC_TMP:
|
||||
pref |= IPV6_PREFER_SRC_TMP;
|
||||
break;
|
||||
case IPV6_PREFER_SRC_PUBTMP_DEFAULT:
|
||||
break;
|
||||
case 0:
|
||||
goto pref_skip_pubtmp;
|
||||
default:
|
||||
goto e_inval;
|
||||
}
|
||||
|
||||
prefmask &= ~(IPV6_PREFER_SRC_PUBLIC|
|
||||
IPV6_PREFER_SRC_TMP);
|
||||
pref_skip_pubtmp:
|
||||
|
||||
/* check HOME/COA conflicts */
|
||||
switch (val & (IPV6_PREFER_SRC_HOME|IPV6_PREFER_SRC_COA)) {
|
||||
case IPV6_PREFER_SRC_HOME:
|
||||
break;
|
||||
case IPV6_PREFER_SRC_COA:
|
||||
pref |= IPV6_PREFER_SRC_COA;
|
||||
case 0:
|
||||
goto pref_skip_coa;
|
||||
default:
|
||||
goto e_inval;
|
||||
}
|
||||
|
||||
prefmask &= ~IPV6_PREFER_SRC_COA;
|
||||
pref_skip_coa:
|
||||
|
||||
/* check CGA/NONCGA conflicts */
|
||||
switch (val & (IPV6_PREFER_SRC_CGA|IPV6_PREFER_SRC_NONCGA)) {
|
||||
case IPV6_PREFER_SRC_CGA:
|
||||
case IPV6_PREFER_SRC_NONCGA:
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
goto e_inval;
|
||||
}
|
||||
|
||||
np->srcprefs = (np->srcprefs & prefmask) | pref;
|
||||
retv = 0;
|
||||
|
||||
retv = __ip6_sock_set_addr_preferences(sk, val);
|
||||
break;
|
||||
}
|
||||
case IPV6_MINHOPCOUNT:
|
||||
if (optlen < sizeof(int))
|
||||
goto e_inval;
|
||||
|
Reference in New Issue
Block a user