diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 0d34f6e..0633e50 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -52,45 +52,50 @@
 #define IPV6_DEFAULT_HOPLIMIT   64
 #define IPV6_DEFAULT_MCASTHOPS	1
 
-/* Limits on Hop-by-Hop and Destination options.
+/* Limits on Hop-by-Hop, Destination, and Segment Routing TLV options.
  *
  * Per RFC8200 there is no limit on the maximum number or lengths of options in
  * Hop-by-Hop or Destination options other then the packet must fit in an MTU.
- * We allow configurable limits in order to mitigate potential denial of
- * service attacks.
+ * Similarly, TLVs in a segment routing header lack a specific limit. We allow
+ * configurable limits in order to mitigate potential denial of service attacks.
  *
  * There are three limits that may be set:
  *   - Limit the number of options in a Hop-by-Hop or Destination options
- *     extension header
+ *     extension header, or the number of TLVs in a Segment Routing Header.
  *   - Limit the byte length of a Hop-by-Hop or Destination options extension
- *     header
- *   - Disallow unknown options
+ *     header, or the length of TLV block in a Segment Routing Header.
+ *   - Disallow unknown options.
  *
  * The limits are expressed in corresponding sysctls:
  *
  * ipv6.sysctl.max_dst_opts_cnt
  * ipv6.sysctl.max_hbh_opts_cnt
+ * ipv6.sysctl.max_srh_opts_cnt
  * ipv6.sysctl.max_dst_opts_len
  * ipv6.sysctl.max_hbh_opts_len
+ * ipv6.sysctl.max_srh_opts_len
  *
  * max_*_opts_cnt is the number of TLVs that are allowed for Destination
- * options or Hop-by-Hop options. If the number is less than zero then unknown
- * TLVs are disallowed and the number of known options that are allowed is the
- * absolute value. Setting the value to INT_MAX indicates no limit.
+ * Options or Hop-by-Hop Options, or the number of TLVs in Segment Routing
+ * TLVs. If the number is less than zero then unknown TLVs are disallowed and
+ * the number of known options that are allowed is the absolute value. Setting
+ * the value to INT_MAX indicates no limit.
  *
- * max_*_opts_len is the length limit in bytes of a Destination or
- * Hop-by-Hop options extension header. Setting the value to INT_MAX
- * indicates no length limit.
+ * max_*_opts_len is the length limit in bytes of a Destination or Hop-by-Hop,
+ * options extension header, or the length of the TLV block in a Segment
+ * Routing Header. Setting the value to INT_MAX indicates no length limit.
  *
  * If a limit is exceeded when processing an extension header the packet is
- * silently discarded.
+ * discarded and an appropriate ICMP error is sent.
  */
 
 /* Default limits for Hop-by-Hop and Destination options */
 #define IP6_DEFAULT_MAX_DST_OPTS_CNT	 8
 #define IP6_DEFAULT_MAX_HBH_OPTS_CNT	 8
+#define IP6_DEFAULT_MAX_SRH_OPTS_CNT	 8
 #define IP6_DEFAULT_MAX_DST_OPTS_LEN	 INT_MAX /* No limit */
 #define IP6_DEFAULT_MAX_HBH_OPTS_LEN	 INT_MAX /* No limit */
+#define IP6_DEFAULT_MAX_SRH_OPTS_LEN	 INT_MAX /* No limit */
 
 /*
  *	Addr type
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 022a0fd..2cb53b3 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -47,8 +47,10 @@ struct netns_sysctl_ipv6 {
 	int flowlabel_reflect;
 	int max_dst_opts_cnt;
 	int max_hbh_opts_cnt;
+	int max_srh_opts_cnt;
 	int max_dst_opts_len;
 	int max_hbh_opts_len;
+	int max_srh_opts_len;
 	int seg6_flowlabel;
 	bool skip_notify_on_dev_down;
 };
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index ceab2fe2..d8dc360 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -862,8 +862,10 @@ static int __net_init inet6_net_init(struct net *net)
 	net->ipv6.sysctl.flowlabel_state_ranges = 0;
 	net->ipv6.sysctl.max_dst_opts_cnt = IP6_DEFAULT_MAX_DST_OPTS_CNT;
 	net->ipv6.sysctl.max_hbh_opts_cnt = IP6_DEFAULT_MAX_HBH_OPTS_CNT;
+	net->ipv6.sysctl.max_srh_opts_cnt = IP6_DEFAULT_MAX_SRH_OPTS_CNT;
 	net->ipv6.sysctl.max_dst_opts_len = IP6_DEFAULT_MAX_DST_OPTS_LEN;
 	net->ipv6.sysctl.max_hbh_opts_len = IP6_DEFAULT_MAX_HBH_OPTS_LEN;
+	net->ipv6.sysctl.max_srh_opts_len = IP6_DEFAULT_MAX_SRH_OPTS_LEN;
 	atomic_set(&net->ipv6.fib6_sernum, 1);
 
 	err = ipv6_init_mibs(net);
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 6d86fac..5fee576 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -162,6 +162,20 @@ static struct ctl_table ipv6_table_template[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "max_srh_opts_number",
+		.data		= &init_net.ipv6.sysctl.max_srh_opts_cnt,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+	{
+		.procname	= "max_srh_tlvs_length",
+		.data		= &init_net.ipv6.sysctl.max_srh_opts_len,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
 	{ }
 };
 
@@ -228,6 +242,8 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
 	ipv6_table[13].data = &net->ipv6.sysctl.max_hbh_opts_len;
 	ipv6_table[14].data = &net->ipv6.sysctl.multipath_hash_policy,
 	ipv6_table[15].data = &net->ipv6.sysctl.seg6_flowlabel;
+	ipv6_table[16].data = &net->ipv6.sysctl.max_srh_opts_cnt;
+	ipv6_table[17].data = &net->ipv6.sysctl.max_srh_opts_len;
 
 	ipv6_route_table = ipv6_route_sysctl_init(net);
 	if (!ipv6_route_table)
