meta-google: gbmc-ncsi-config: Add relay support for the bridge

We may have multiple BMCs running on the internal gbmcbr network via USB
links to attached trays. These BMCs do not have a direct connection to
the network, and require the NCSI BMC to relay all of their traffic
(including DHCP) out opf the machine. This patch enables dhcrelay to run
on the NCSI interface and proxy all DHCP traffic from the bridge out of
the machine.

Change-Id: I60f97ae2d64289c7b706b3d0a6c8fb79a931e485
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/meta-google/recipes-connectivity/dhcp/dhcp-relay_%.bbappend b/meta-google/recipes-connectivity/dhcp/dhcp-relay_%.bbappend
new file mode 100644
index 0000000..4efa9f2
--- /dev/null
+++ b/meta-google/recipes-connectivity/dhcp/dhcp-relay_%.bbappend
@@ -0,0 +1,4 @@
+# LTO and static enabled to reduce image size, saves ~50%
+CFLAGS:append:gbmc = " -flto"
+EXTRA_OECONF:remove:gbmc = "--disable-static"
+EXTRA_OECONF:append:gbmc = " --enable-relay-port --disable-shared"
diff --git a/meta-google/recipes-google/ncsi/files/-bmc-gbmcbrncsidhcp.netdev b/meta-google/recipes-google/ncsi/files/-bmc-gbmcbrncsidhcp.netdev
new file mode 100644
index 0000000..58f13bd
--- /dev/null
+++ b/meta-google/recipes-google/ncsi/files/-bmc-gbmcbrncsidhcp.netdev
@@ -0,0 +1,5 @@
+[NetDev]
+Name=gbmcbrncsidhcp
+Kind=veth
+[Peer]
+Name=gbmcncsidhcp
diff --git a/meta-google/recipes-google/ncsi/files/-bmc-gbmcbrncsidhcp.network b/meta-google/recipes-google/ncsi/files/-bmc-gbmcbrncsidhcp.network
new file mode 100644
index 0000000..5474bff
--- /dev/null
+++ b/meta-google/recipes-google/ncsi/files/-bmc-gbmcbrncsidhcp.network
@@ -0,0 +1,4 @@
+[Match]
+Name=gbmcbrncsidhcp
+[Network]
+Bridge=gbmcbr
diff --git a/meta-google/recipes-google/ncsi/files/-bmc-gbmcncsidhcp.netdev b/meta-google/recipes-google/ncsi/files/-bmc-gbmcncsidhcp.netdev
new file mode 100644
index 0000000..08235aa
--- /dev/null
+++ b/meta-google/recipes-google/ncsi/files/-bmc-gbmcncsidhcp.netdev
@@ -0,0 +1,5 @@
+[NetDev]
+Name=gbmcncsidhcp
+Kind=veth
+[Peer]
+Name=gbmcbrncsidhcp
diff --git a/meta-google/recipes-google/ncsi/files/-bmc-gbmcncsidhcp.network b/meta-google/recipes-google/ncsi/files/-bmc-gbmcncsidhcp.network
new file mode 100644
index 0000000..868d24b
--- /dev/null
+++ b/meta-google/recipes-google/ncsi/files/-bmc-gbmcncsidhcp.network
@@ -0,0 +1,9 @@
+[Match]
+Name=gbmcncsidhcp
+[Network]
+DHCP=false
+IPv6AcceptRA=false
+LLMNR=false
+MulticastDNS=false
+LinkLocalAddressing=ipv6
+Address=fdb5:0481:10ce::1/64
diff --git a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in
index 938dca3..f712720 100644
--- a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in
+++ b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in
@@ -31,4 +31,10 @@
         ip6 daddr fdb5:0481:10ce::/64 drop
         ip6 saddr fdb5:0481:10ce::/64 drop
     }
+    chain ncsi_dhcp_input {
+        type filter hook input priority 0; policy drop;
+        iifname != ncsigbmc accept
+        ip6 nexthdr icmpv6 accept
+        udp dport 547 accept
+    }
 }
diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-dhcrelay.service.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-dhcrelay.service.in
new file mode 100644
index 0000000..5e03455
--- /dev/null
+++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-dhcrelay.service.in
@@ -0,0 +1,13 @@
+[Unit]
+Description=gBMC DHCP Relay Agent Daemon
+After=network.target
+StartLimitIntervalSec=10
+StartLimitBurst=3
+
+[Service]
+Restart=always
+RestartSec=5
+ExecStart=/usr/sbin/dhcrelay -d --no-pid -rp 3967 -l gbmcncsidhcp -u @NCSI_IF@
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb
index 6480be1..0302ed8 100644
--- a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb
+++ b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb
@@ -6,7 +6,12 @@
 inherit systemd
 
 SRC_URI += " \
+  file://-bmc-gbmcbrncsidhcp.netdev \
+  file://-bmc-gbmcbrncsidhcp.network \
+  file://-bmc-gbmcncsidhcp.netdev \
+  file://-bmc-gbmcncsidhcp.network \
   file://50-gbmc-ncsi.rules.in \
+  file://gbmc-ncsi-dhcrelay.service.in \
   file://gbmc-ncsi-sslh.socket.in \
   file://gbmc-ncsi-sslh.service \
   file://gbmc-ncsi-nft.sh.in \
@@ -17,6 +22,7 @@
 S = "${WORKDIR}"
 
 RDEPENDS:${PN} += " \
+  dhcp-relay \
   gbmc-ip-monitor \
   ncsid \
   nftables-systemd \
@@ -29,6 +35,7 @@
   "
 
 SYSTEMD_SERVICE:${PN} += " \
+  gbmc-ncsi-dhcrelay.service \
   gbmc-ncsi-sslh.service \
   gbmc-ncsi-sslh.socket \
   gbmc-ncsi-set-nicenabled.service \
@@ -47,6 +54,16 @@
   echo "net.ipv6.conf.$if_name.dad_transmits=0" \
     >>${D}${sysconfdir}/sysctl.d/25-gbmc-ncsi.conf
 
+  install -d -m0755 ${D}${systemd_unitdir}/network
+  install -m0644 ${WORKDIR}/-bmc-gbmcbrncsidhcp.netdev \
+    ${D}${systemd_unitdir}/network/
+  install -m0644 ${WORKDIR}/-bmc-gbmcbrncsidhcp.network \
+    ${D}${systemd_unitdir}/network/
+  install -m0644 ${WORKDIR}/-bmc-gbmcncsidhcp.netdev \
+    ${D}${systemd_unitdir}/network/
+  install -m0644 ${WORKDIR}/-bmc-gbmcncsidhcp.network \
+    ${D}${systemd_unitdir}/network/
+
   netdir=${D}${systemd_unitdir}/network/00-bmc-$if_name.network.d
   install -d -m0755 "$netdir"
   echo '[Network]' >>"$netdir"/gbmc-ncsi.conf
@@ -80,4 +97,13 @@
 
   sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-set-nicenabled.service.in \
     >${D}${systemd_system_unitdir}/gbmc-ncsi-set-nicenabled.service
+
+  sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-dhcrelay.service.in \
+    >${D}${systemd_system_unitdir}/gbmc-ncsi-dhcrelay.service
+}
+
+do_rm_work:prepend() {
+  # HACK: Work around broken do_rm_work not properly calling rm with `--`
+  # It doesn't like filenames that start with `-`
+  rm -rf -- ${WORKDIR}/-*
 }
diff --git a/meta-google/recipes-kernel/linux/files/gbmc.cfg b/meta-google/recipes-kernel/linux/files/gbmc.cfg
index 89e1ef9..056ee91 100644
--- a/meta-google/recipes-kernel/linux/files/gbmc.cfg
+++ b/meta-google/recipes-kernel/linux/files/gbmc.cfg
@@ -36,6 +36,7 @@
 CONFIG_BRIDGE_NETFILTER=y
 CONFIG_NF_TABLES_BRIDGE=y
 CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_VETH=y
 
 # Remove features we won't use
 CONFIG_WLAN=n