|
@@ -758,6 +758,27 @@ static int ipv6_renew_option(void *ohdr,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * ipv6_renew_options - replace a specific ext hdr with a new one.
|
|
|
+ *
|
|
|
+ * @sk: sock from which to allocate memory
|
|
|
+ * @opt: original options
|
|
|
+ * @newtype: option type to replace in @opt
|
|
|
+ * @newopt: new option of type @newtype to replace (user-mem)
|
|
|
+ * @newoptlen: length of @newopt
|
|
|
+ *
|
|
|
+ * Returns a new set of options which is a copy of @opt with the
|
|
|
+ * option type @newtype replaced with @newopt.
|
|
|
+ *
|
|
|
+ * @opt may be NULL, in which case a new set of options is returned
|
|
|
+ * containing just @newopt.
|
|
|
+ *
|
|
|
+ * @newopt may be NULL, in which case the specified option type is
|
|
|
+ * not copied into the new set of options.
|
|
|
+ *
|
|
|
+ * The new set of options is allocated from the socket option memory
|
|
|
+ * buffer of @sk.
|
|
|
+ */
|
|
|
struct ipv6_txoptions *
|
|
|
ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
|
|
|
int newtype,
|
|
@@ -830,6 +851,34 @@ out:
|
|
|
return ERR_PTR(err);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * ipv6_renew_options_kern - replace a specific ext hdr with a new one.
|
|
|
+ *
|
|
|
+ * @sk: sock from which to allocate memory
|
|
|
+ * @opt: original options
|
|
|
+ * @newtype: option type to replace in @opt
|
|
|
+ * @newopt: new option of type @newtype to replace (kernel-mem)
|
|
|
+ * @newoptlen: length of @newopt
|
|
|
+ *
|
|
|
+ * See ipv6_renew_options(). The difference is that @newopt is
|
|
|
+ * kernel memory, rather than user memory.
|
|
|
+ */
|
|
|
+struct ipv6_txoptions *
|
|
|
+ipv6_renew_options_kern(struct sock *sk, struct ipv6_txoptions *opt,
|
|
|
+ int newtype, struct ipv6_opt_hdr *newopt,
|
|
|
+ int newoptlen)
|
|
|
+{
|
|
|
+ struct ipv6_txoptions *ret_val;
|
|
|
+ const mm_segment_t old_fs = get_fs();
|
|
|
+
|
|
|
+ set_fs(KERNEL_DS);
|
|
|
+ ret_val = ipv6_renew_options(sk, opt, newtype,
|
|
|
+ (struct ipv6_opt_hdr __user *)newopt,
|
|
|
+ newoptlen);
|
|
|
+ set_fs(old_fs);
|
|
|
+ return ret_val;
|
|
|
+}
|
|
|
+
|
|
|
struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
|
|
|
struct ipv6_txoptions *opt)
|
|
|
{
|