<Middlebox name="lb4">
  <Description>
    Layer-4 load balancer in dual-legged configuration.  
    Based on BalanceNg software load balancer.
    Default gateway of web servers set to the load balancer.
  </Description>  
  <Zones>
    <Zone name="inet" description="Internet" />
    <Zone name="srvr" description="Web server farm" />
  </Zones>
  <TransformationFns>
    <TransformationFn name="Dnat_fwd">
      <Param description="selected webserver">w</Param>
      <Rewrite field="dstmac" value="Mac(w)" />
      <Rewrite field="dstip" value="Ip(w)" />
    </TransformationFn>
    <TransformationFn name="Dnat_rev">
      <Rewrite field="srcmac" value="Mac(LB)" />
      <Rewrite field="dstmac" value="Mac(GW)" />
      <Rewrite field="srcip" value="Ip(LB)" />
    </TransformationFn>
  </TransformationFns>
  <ProcessingRules>
    <Rule id="1">
      <LHS>
        <Z>inet</Z>
        <I>h.dstmac == Mac(LB) AND h.dstip == Ip(LB) AND h.dstport == 80</I>
        <C>NewFlow?</C>
      </LHS>
      <RHS>
        <Assign>w = SrvrSelect</Assign>
        <Assign>h1 = Dnat_fwd(h,w)</Assign>
        <Emit zone="srvr">
          <Hdr>h1</Hdr>
          <Payload>d</Payload>
        </Emit>
        <SetState zone="inet" key="h.5tpl" value="w" />
        <SetState zone="srvr" key="Rev(h1).5tpl" value="TRUE" />
      </RHS>
    </Rule>
    <Rule id="2">
      <LHS>
        <Z>inet</Z>
        <I>h.dstmac == Mac(LB) AND h.dstip == Ip(LB) AND h.dstport == 80</I>
        <C>! NewFlow?</C>
        <GetState zone="inet" key="h.5tpl" assignto="s" />
      </LHS>
      <RHS>
        <Assign>h1 = Dnat_fwd(h,s)</Assign>
        <Emit zone="srvr">
          <Hdr>h1</Hdr>
          <Payload>d</Payload>
        </Emit>
      </RHS>
    </Rule>
    <Rule id="3">
      <LHS>
        <Z>srvr</Z>
        <I>h.srcmac == Mac(W) AND h.srcip == Ip(W) AND h.srcport == 80</I>
        <GetState zone="srvr" key="h.5tpl" />
      </LHS>
      <RHS>
        <Assign>h1 = Dnat_rev(h)</Assign>
        <Emit zone="inet">
          <Hdr>h1</Hdr>
          <Payload>d</Payload>
        </Emit>
      </RHS>
    </Rule>
  </ProcessingRules>
  <AuxTraffic>
    <Rule id="4">
      <LHS>
        Periodic
      </LHS>
      <RHS>
        <Emit zone="srvr">
          Probe_srvr(W)
        </Emit>
      </RHS>
    </Rule>
    <Rule id="5">
      <LHS>
        <Z>inet</Z>
        <GetState zone="inet" key="h.5tpl" assignto="s" />
        !<GetState key="Ip(s)" />
      </LHS>
      <RHS>
        <Emit zone="srvr">
          ArpReq(Ip(s))
        </Emit>
      </RHS>
    </Rule>
    <Rule id="6">
      <LHS>
        <Z>srvr</Z>
        <I>p == ArpReply(ip,mac)</I>
      </LHS>
      <RHS>
        <SetState key="ip" value="mac" />
      </RHS>
    </Rule>
  </AuxTraffic>
</Middlebox>


