/* Demultiple the packet. the packet delivery is processed in two passes. The first pass will enqueue a shared copy of the packet to each IP4 child that accepts the packet. The second pass will deliver a non-shared copy of the packet to each IP4 child that has pending receive requests. Data is copied if more than one child wants to consume the packet because each IP child needs its own copy of the packet to make changes. */
EFI_STATUS Ip4Demultiplex(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet, IN UINT8 *Option, IN UINT32 OptionLen)
/* Demultiple the packet. the packet delivery is processed in two passes. The first pass will enqueue a shared copy of the packet to each IP4 child that accepts the packet. The second pass will deliver a non-shared copy of the packet to each IP4 child that has pending receive requests. Data is copied if more than one child wants to consume the packet because each IP child needs its own copy of the packet to make changes. */
EFI_STATUS Ip4Demultiplex(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet, IN UINT8 *Option, IN UINT32 OptionLen)
{
  LIST_ENTRY     *Entry;
  IP4_INTERFACE  *IpIf;
  INTN           Enqueued;
  Enqueued = 0;
  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);
    if (IpIf->Configured) {
      Enqueued += Ip4InterfaceEnquePacket (
                    IpSb,
                    Head,
                    Packet,
                    Option,
                    OptionLen,
                    IpIf
                    );
    }
  }
  NetbufFree (Packet);
  if (Enqueued == 0) {
    return EFI_NOT_FOUND;
  }
  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);
    if (IpIf->Configured) {
      Ip4InterfaceDeliverPacket (IpSb, IpIf);
    }
  }
  return EFI_SUCCESS;
}