net: ipv6: Add support for default gateway discovery.

In IPv6, the default gateway and prefix length are determined by receiving
a router advertisement as defined in -
https://www.rfc-editor.org/rfc/rfc4861.

Add support for sending router solicitation (RS) and processing router
advertisements (RA).

If the RA has prefix info option and following conditions are met, then
gatewayip6 and net_prefix_length of ip6addr env variables are initialized.
These are later consumed by IPv6 code for non-local destination IP.

- "Router Lifetime" != 0
- Prefix is NOT link-local prefix (0xfe80::/10)
- L flag is 1
- "Valid Lifetime" != 0

Timing Parameters:
- MAX_RTR_SOLICITATION_DELAY (0-1s)
- RTR_SOLICITATION_INTERVAL (4s) (min retransmit delay)
- MAX_RTR_SOLICITATIONS (3 RS transmissions)

The functionality is enabled by CONFIG_IPV6_ROUTER_DISCOVERY and invoked
automatically from net_init_loop().

Signed-off-by: Ehsan Mohandesi <emohandesi@linux.microsoft.com>
Tested-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>Reviewed-by:
Tested-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>
Reviewed-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>
Tested-by: Sergei Antonov <saproj@gmail.com>
Reviewed-by: Sergei Antonov <saproj@gmail.com>
diff --git a/include/ndisc.h b/include/ndisc.h
index f6f8eb6..d0fe3ac 100644
--- a/include/ndisc.h
+++ b/include/ndisc.h
@@ -19,6 +19,20 @@
 	__u8		opt[0];
 };
 
+/* struct rs_msg - ICMPv6 Router Solicitation message format */
+struct rs_msg {
+	struct icmp6hdr	icmph;
+	__u8		opt[0];
+};
+
+/* struct ra_msg - ICMPv6 Router Advertisement message format */
+struct ra_msg {
+	struct icmp6hdr	icmph;
+	__u32	reachable_time;
+	__u32	retransmission_timer;
+	__u8	opt[0];
+};
+
 /* struct echo_msg - ICMPv6 echo request/reply message format */
 struct echo_msg {
 	struct icmp6hdr	icmph;
@@ -57,6 +71,11 @@
  */
 void ndisc_init(void);
 
+/*
+ * ip6_send_rs() - Send IPv6 Router Solicitation Message
+ */
+void ip6_send_rs(void);
+
 /**
  * ndisc_receive() - Handle ND packet
  *
@@ -78,6 +97,8 @@
  * Return: 0 if no timeout, -1 otherwise
  */
 int ndisc_timeout_check(void);
+bool validate_ra(struct ip6_hdr *ip6);
+int process_ra(struct ip6_hdr *ip6, int len);
 #else
 static inline void ndisc_init(void)
 {
@@ -97,6 +118,20 @@
 {
 	return 0;
 }
+
+static inline void ip6_send_rs(void)
+{
+}
+
+static inline bool validate_ra(struct ip6_hdr *ip6)
+{
+	return true;
+}
+
+static inline int process_ra(struct ip6_hdr *ip6, int len)
+{
+	return 0;
+}
 #endif
 
 #endif /* __NDISC_H__ */